aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2013-04-11 00:09:05 +0000
committerSean Callanan <scallanan@apple.com>2013-04-11 00:09:05 +0000
commit96d2730a7b490d909450c20e5ae13964cf7a42ed (patch)
tree35da02563db968fcdf59c6ceb905c1e7c08767f7
parent5143243484f38158a8ac7a687b35575c85cf28ac (diff)
downloadllvm-96d2730a7b490d909450c20e5ae13964cf7a42ed.zip
llvm-96d2730a7b490d909450c20e5ae13964cf7a42ed.tar.gz
llvm-96d2730a7b490d909450c20e5ae13964cf7a42ed.tar.bz2
Added a Materializer class that contains
information about each variable that needs to be materialized for an expression to work. The next step is to migrate all materialization code from ClangExpressionDeclMap to Materializer, and to use it for variable materialization. llvm-svn: 179245
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionDeclMap.h12
-rw-r--r--lldb/include/lldb/Expression/ClangUserExpression.h4
-rw-r--r--lldb/include/lldb/Expression/Materializer.h379
-rw-r--r--lldb/include/lldb/lldb-forward.h1
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj6
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp26
-rw-r--r--lldb/source/Expression/ClangUserExpression.cpp5
-rw-r--r--lldb/source/Expression/ClangUtilityFunction.cpp2
-rw-r--r--lldb/source/Expression/Materializer.cpp275
9 files changed, 704 insertions, 6 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
index e72c65e5..e228f29 100644
--- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
+++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
@@ -69,6 +69,9 @@ public:
/// If true, inhibits the normal deallocation of the memory for
/// the result persistent variable, and instead marks the variable
/// as persisting.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when parsing.
//------------------------------------------------------------------
ClangExpressionDeclMap (bool keep_result_in_memory,
ExecutionContext &exe_ctx);
@@ -85,11 +88,16 @@ public:
/// The execution context to use when finding types for variables.
/// Also used to find a "scratch" AST context to store result types.
///
+ /// @param[in] materializer
+ /// If non-NULL, the materializer to populate with information about
+ /// the variables to use
+ ///
/// @return
/// True if parsing is possible; false if it is unsafe to continue.
//------------------------------------------------------------------
bool
- WillParse (ExecutionContext &exe_ctx);
+ WillParse (ExecutionContext &exe_ctx,
+ Materializer *materializer);
//------------------------------------------------------------------
/// [Used by ClangExpressionParser] For each variable that had an unknown
@@ -674,6 +682,7 @@ private:
m_sym_ctx(),
m_persistent_vars(NULL),
m_enable_lookups(false),
+ m_materializer(NULL),
m_decl_map(decl_map)
{
}
@@ -693,6 +702,7 @@ private:
ClangPersistentVariables *m_persistent_vars; ///< The persistent variables for the process.
bool m_enable_lookups; ///< Set to true during parsing if we have found the first "$__lldb" name.
TargetInfo m_target_info; ///< Basic information about the target.
+ Materializer *m_materializer; ///< If non-NULL, the materializer to use when reporting used variables.
private:
ClangExpressionDeclMap &m_decl_map;
DISALLOW_COPY_AND_ASSIGN (ParserVars);
diff --git a/lldb/include/lldb/Expression/ClangUserExpression.h b/lldb/include/lldb/Expression/ClangUserExpression.h
index 03cb355..8d87fa8 100644
--- a/lldb/include/lldb/Expression/ClangUserExpression.h
+++ b/lldb/include/lldb/Expression/ClangUserExpression.h
@@ -420,8 +420,10 @@ private:
std::string m_transformed_text; ///< The text of the expression, as send to the parser
ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression.
- std::auto_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing and materializing the expression.
+ std::auto_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing the expression.
+
std::auto_ptr<IRExecutionUnit> m_execution_unit_ap; ///< The execution unit the expression is stored in.
+ std::auto_ptr<Materializer> m_materializer_ap; ///< The materializer to use when running the expression.
std::auto_ptr<ASTResultSynthesizer> m_result_synthesizer; ///< The result synthesizer, if one is needed.
diff --git a/lldb/include/lldb/Expression/Materializer.h b/lldb/include/lldb/Expression/Materializer.h
new file mode 100644
index 0000000..4171503
--- /dev/null
+++ b/lldb/include/lldb/Expression/Materializer.h
@@ -0,0 +1,379 @@
+//===-- Materializer.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Materializer_h
+#define lldb_Materializer_h
+
+#include "lldb/lldb-private-types.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/IRMemoryMap.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+#include <vector>
+
+namespace lldb_private
+{
+
+class Materializer
+{
+public:
+ Materializer ();
+
+ class Dematerializer
+ {
+ public:
+ void Dematerialize(Error &err);
+ private:
+ friend class Materializer;
+
+ Dematerializer (Materializer &materializer,
+ lldb::StackFrameSP &frame_sp,
+ IRMemoryMap &map,
+ lldb::addr_t process_address) :
+ m_materializer(materializer),
+ m_frame_wp(frame_sp),
+ m_map(map),
+ m_process_address(process_address)
+ {
+ }
+
+ Materializer &m_materializer;
+ lldb::StackFrameWP m_frame_wp;
+ IRMemoryMap &m_map;
+ lldb::addr_t m_process_address;
+ };
+
+ Dematerializer Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err);
+
+ uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
+ uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
+ uint32_t AddResultVariable (const ClangASTType &type, Error &err);
+ uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
+ uint32_t AddRegister (const RegisterInfo &register_info, Error &err);
+
+ uint32_t GetStructAlignment ();
+
+ class Entity
+ {
+ public:
+ Entity () :
+ m_alignment(1),
+ m_size(0),
+ m_offset(0)
+ {
+ }
+
+ virtual ~Entity ()
+ {
+ }
+
+ virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
+ virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
+
+ uint32_t GetAlignment ()
+ {
+ return m_alignment;
+ }
+
+ uint32_t GetSize ()
+ {
+ return m_size;
+ }
+
+ uint32_t GetOffset ()
+ {
+ return m_offset;
+ }
+
+ void SetOffset (uint32_t offset)
+ {
+ m_offset = offset;
+ }
+ protected:
+ void SetSizeAndAlignmentFromType (ClangASTType &type);
+
+ uint32_t m_alignment;
+ uint32_t m_size;
+ uint32_t m_offset;
+ };
+
+private:
+ uint32_t AddStructMember (Entity &entity);
+
+ typedef std::unique_ptr<Entity> EntityUP;
+ typedef std::vector<EntityUP> EntityVector;
+
+ unsigned m_result_index;
+ Mutex m_needs_dematerialize;
+ EntityVector m_entities;
+ uint32_t m_current_offset;
+ uint32_t m_struct_alignment;
+};
+
+}
+
+#endif
+//===-- Materializer.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Materializer_h
+#define lldb_Materializer_h
+
+#include "lldb/lldb-private-types.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/IRMemoryMap.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+#include <vector>
+
+namespace lldb_private
+{
+
+class Materializer
+{
+public:
+ Materializer ();
+
+ class Dematerializer
+ {
+ public:
+ void Dematerialize(Error &err);
+ private:
+ friend class Materializer;
+
+ Dematerializer (Materializer &materializer,
+ lldb::StackFrameSP &frame_sp,
+ IRMemoryMap &map,
+ lldb::addr_t process_address) :
+ m_materializer(materializer),
+ m_frame_wp(frame_sp),
+ m_map(map),
+ m_process_address(process_address)
+ {
+ }
+
+ Materializer &m_materializer;
+ lldb::StackFrameWP m_frame_wp;
+ IRMemoryMap &m_map;
+ lldb::addr_t m_process_address;
+ };
+
+ Dematerializer Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err);
+
+ uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
+ uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
+ uint32_t AddResultVariable (const ClangASTType &type, Error &err);
+ uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
+ uint32_t AddRegister (const RegisterInfo &register_info, Error &err);
+
+ uint32_t GetStructAlignment ();
+
+ class Entity
+ {
+ public:
+ Entity () :
+ m_alignment(1),
+ m_size(0),
+ m_offset(0)
+ {
+ }
+
+ virtual ~Entity ()
+ {
+ }
+
+ virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
+ virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
+
+ uint32_t GetAlignment ()
+ {
+ return m_alignment;
+ }
+
+ uint32_t GetSize ()
+ {
+ return m_size;
+ }
+
+ uint32_t GetOffset ()
+ {
+ return m_offset;
+ }
+
+ void SetOffset (uint32_t offset)
+ {
+ m_offset = offset;
+ }
+ protected:
+ void SetSizeAndAlignmentFromType (ClangASTType &type);
+
+ uint32_t m_alignment;
+ uint32_t m_size;
+ uint32_t m_offset;
+ };
+
+private:
+ uint32_t AddStructMember (Entity &entity);
+
+ typedef std::unique_ptr<Entity> EntityUP;
+ typedef std::vector<EntityUP> EntityVector;
+
+ unsigned m_result_index;
+ Mutex m_needs_dematerialize;
+ EntityVector m_entities;
+ uint32_t m_current_offset;
+ uint32_t m_struct_alignment;
+};
+
+}
+
+#endif
+//===-- Materializer.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Materializer_h
+#define lldb_Materializer_h
+
+#include "lldb/lldb-private-types.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/IRMemoryMap.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+#include <vector>
+
+namespace lldb_private
+{
+
+class Materializer
+{
+public:
+ Materializer ();
+
+ class Dematerializer
+ {
+ public:
+ void Dematerialize(Error &err);
+ private:
+ friend class Materializer;
+
+ Dematerializer (Materializer &materializer,
+ lldb::StackFrameSP &frame_sp,
+ IRMemoryMap &map,
+ lldb::addr_t process_address) :
+ m_materializer(materializer),
+ m_frame_wp(frame_sp),
+ m_map(map),
+ m_process_address(process_address)
+ {
+ }
+
+ Materializer &m_materializer;
+ lldb::StackFrameWP m_frame_wp;
+ IRMemoryMap &m_map;
+ lldb::addr_t m_process_address;
+ };
+
+ Dematerializer Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err);
+
+ uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
+ uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
+ uint32_t AddResultVariable (const ClangASTType &type, Error &err);
+ uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
+ uint32_t AddRegister (const RegisterInfo &register_info, Error &err);
+
+ uint32_t GetStructAlignment ()
+ {
+ return m_struct_alignment;
+ }
+
+ uint32_t GetStructSize ()
+ {
+ return m_current_offset;
+ }
+
+ uint32_t GetNumEntities ()
+ {
+ return m_entities.size();
+ }
+
+ class Entity
+ {
+ public:
+ Entity () :
+ m_alignment(1),
+ m_size(0),
+ m_offset(0)
+ {
+ }
+
+ virtual ~Entity ()
+ {
+ }
+
+ virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
+ virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
+
+ uint32_t GetAlignment ()
+ {
+ return m_alignment;
+ }
+
+ uint32_t GetSize ()
+ {
+ return m_size;
+ }
+
+ uint32_t GetOffset ()
+ {
+ return m_offset;
+ }
+
+ void SetOffset (uint32_t offset)
+ {
+ m_offset = offset;
+ }
+ protected:
+ void SetSizeAndAlignmentFromType (ClangASTType &type);
+
+ uint32_t m_alignment;
+ uint32_t m_size;
+ uint32_t m_offset;
+ };
+
+private:
+ uint32_t AddStructMember (Entity &entity);
+
+ typedef std::unique_ptr<Entity> EntityUP;
+ typedef std::vector<EntityUP> EntityVector;
+
+ unsigned m_result_index;
+ Mutex m_needs_dematerialize;
+ EntityVector m_entities;
+ uint32_t m_current_offset;
+ uint32_t m_struct_alignment;
+};
+
+}
+
+#endif
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 4db56bbd..0baf3aa 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -125,6 +125,7 @@ class Listener;
class Log;
class LogChannel;
class Mangled;
+class Materializer;
class Module;
class ModuleList;
class ModuleSpec;
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index 0c8cf8d..e9c4f3c 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -498,6 +498,7 @@
49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D8FB3513B558DE00411094 /* ClangASTImporter.cpp */; };
49DA65031485C92A005FF180 /* AppleObjCTypeVendor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA65021485C92A005FF180 /* AppleObjCTypeVendor.cpp */; };
49DCF6FE170E6B4A0092F75E /* IRMemoryMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF6FD170E6B4A0092F75E /* IRMemoryMap.cpp */; };
+ 49DCF702170E70120092F75E /* Materializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF700170E70120092F75E /* Materializer.cpp */; };
4C6649A014EEE7F100B0316F /* StreamCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C66499F14EEE7F100B0316F /* StreamCallback.h */; };
4C6649A314EEE81000B0316F /* StreamCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C6649A214EEE81000B0316F /* StreamCallback.cpp */; };
4C701C1E15ABB70C00B50001 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26D55234159A7DB100708D8D /* libxml2.dylib */; };
@@ -1462,6 +1463,8 @@
49DA65021485C92A005FF180 /* AppleObjCTypeVendor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppleObjCTypeVendor.cpp; sourceTree = "<group>"; };
49DA65041485C942005FF180 /* AppleObjCTypeVendor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleObjCTypeVendor.h; sourceTree = "<group>"; };
49DCF6FD170E6B4A0092F75E /* IRMemoryMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRMemoryMap.cpp; path = source/Expression/IRMemoryMap.cpp; sourceTree = "<group>"; };
+ 49DCF6FF170E6FD90092F75E /* Materializer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Materializer.h; path = include/lldb/Expression/Materializer.h; sourceTree = "<group>"; };
+ 49DCF700170E70120092F75E /* Materializer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Materializer.cpp; path = source/Expression/Materializer.cpp; sourceTree = "<group>"; };
49E45FA911F660DC008F7B28 /* ClangASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTType.h; path = include/lldb/Symbol/ClangASTType.h; sourceTree = "<group>"; };
49E45FAD11F660FE008F7B28 /* ClangASTType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTType.cpp; path = source/Symbol/ClangASTType.cpp; sourceTree = "<group>"; };
49EC3E98118F90AC00B1265E /* ThreadPlanCallFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanCallFunction.cpp; path = source/Target/ThreadPlanCallFunction.cpp; sourceTree = "<group>"; };
@@ -2903,6 +2906,8 @@
49307AAD11DEA4D90081F992 /* IRForTarget.cpp */,
496B015A1406DEB100F830D5 /* IRInterpreter.h */,
496B01581406DE8900F830D5 /* IRInterpreter.cpp */,
+ 49DCF6FF170E6FD90092F75E /* Materializer.h */,
+ 49DCF700170E70120092F75E /* Materializer.cpp */,
);
name = Expression;
sourceTree = "<group>";
@@ -4009,6 +4014,7 @@
2689002F13353E0400698AC0 /* ArchSpec.cpp in Sources */,
2689003013353E0400698AC0 /* Baton.cpp in Sources */,
2689003113353E0400698AC0 /* Broadcaster.cpp in Sources */,
+ 49DCF702170E70120092F75E /* Materializer.cpp in Sources */,
2689003213353E0400698AC0 /* Communication.cpp in Sources */,
2689003313353E0400698AC0 /* Connection.cpp in Sources */,
2689003413353E0400698AC0 /* ConnectionFileDescriptor.cpp in Sources */,
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 00724b4..35c9474 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -27,6 +27,7 @@
#include "lldb/Expression/ASTDumper.h"
#include "lldb/Expression/ClangASTSource.h"
#include "lldb/Expression/ClangPersistentVariables.h"
+#include "lldb/Expression/Materializer.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangNamespaceDecl.h"
@@ -74,7 +75,8 @@ ClangExpressionDeclMap::~ClangExpressionDeclMap()
}
bool
-ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx)
+ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
+ Materializer *materializer)
{
ClangASTMetrics::ClearLocalCounters();
@@ -106,11 +108,12 @@ ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx)
}
m_parser_vars->m_target_info = GetTargetInfo();
+ m_parser_vars->m_materializer = materializer;
return true;
}
-void
+void
ClangExpressionDeclMap::DidParse()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -3409,6 +3412,12 @@ ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP v
ConstString entity_name(decl_name.c_str());
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (valobj));
+ if (m_parser_vars->m_materializer)
+ {
+ Error err;
+ m_parser_vars->m_materializer->AddVariable(var, err);
+ }
+
assert (entity.get());
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
@@ -3499,6 +3508,12 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
m_parser_vars->m_target_info.address_byte_size));
assert (entity.get());
+ if (m_parser_vars->m_materializer)
+ {
+ Error err;
+ m_parser_vars->m_materializer->AddSymbol(symbol, err);
+ }
+
std::auto_ptr<Value> symbol_location(new Value);
const Address &symbol_address = symbol.GetAddress();
@@ -3613,6 +3628,13 @@ ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size));
assert (entity.get());
+
+ if (m_parser_vars->m_materializer && reg_info)
+ {
+ Error err;
+ m_parser_vars->m_materializer->AddRegister(*reg_info, err);
+ }
+
std::string decl_name(context.m_decl_name.getAsString());
entity->SetName (ConstString (decl_name.c_str()));
entity->SetRegisterInfo (reg_info);
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp
index b0acfa0..4ecd189 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Expression/ClangUserExpression.cpp
@@ -29,6 +29,7 @@
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Expression/ClangUserExpression.h"
#include "lldb/Expression/ExpressionSourceCode.h"
+#include "lldb/Expression/Materializer.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -430,9 +431,11 @@ ClangUserExpression::Parse (Stream &error_stream,
// Parse the expression
//
+ m_materializer_ap.reset(new Materializer());
+
m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
- if (!m_expr_decl_map->WillParse(exe_ctx))
+ if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
{
error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
return false;
diff --git a/lldb/source/Expression/ClangUtilityFunction.cpp b/lldb/source/Expression/ClangUtilityFunction.cpp
index 61b0702..3fcc249 100644
--- a/lldb/source/Expression/ClangUtilityFunction.cpp
+++ b/lldb/source/Expression/ClangUtilityFunction.cpp
@@ -102,7 +102,7 @@ ClangUtilityFunction::Install (Stream &error_stream,
m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
- if (!m_expr_decl_map->WillParse(exe_ctx))
+ if (!m_expr_decl_map->WillParse(exe_ctx, NULL))
{
error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
return false;
diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
new file mode 100644
index 0000000..549e777
--- /dev/null
+++ b/lldb/source/Expression/Materializer.cpp
@@ -0,0 +1,275 @@
+//===-- Materializer.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Expression/ClangExpressionVariable.h"
+#include "lldb/Expression/Materializer.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/Variable.h"
+#include "lldb/Target/ExecutionContext.h"
+
+using namespace lldb_private;
+
+uint32_t
+Materializer::AddStructMember (Entity &entity)
+{
+ uint32_t size = entity.GetSize();
+ uint32_t alignment = entity.GetAlignment();
+
+ uint32_t ret;
+
+ if (!m_current_offset)
+ m_struct_alignment = alignment;
+
+ if (m_current_offset % alignment)
+ m_current_offset += (alignment - (m_current_offset % alignment));
+
+ ret = m_current_offset;
+
+ m_current_offset += size;
+
+ return ret;
+}
+
+void
+Materializer::Entity::SetSizeAndAlignmentFromType (ClangASTType &type)
+{
+ m_size = type.GetTypeByteSize();
+
+ uint32_t bit_alignment = type.GetTypeBitAlign();
+
+ if (bit_alignment % 8)
+ {
+ bit_alignment += 8;
+ bit_alignment &= ~((uint32_t)0x111u);
+ }
+
+ m_alignment = bit_alignment / 8;
+}
+
+class EntityPersistentVariable : public Materializer::Entity
+{
+public:
+ EntityPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp) :
+ Entity(),
+ m_persistent_variable_sp(persistent_variable_sp)
+ {
+ ClangASTType type(m_persistent_variable_sp->GetClangAST(),
+ m_persistent_variable_sp->GetClangType());
+
+ SetSizeAndAlignmentFromType(type);
+ }
+
+ virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+
+ virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+private:
+ lldb::ClangExpressionVariableSP m_persistent_variable_sp;
+};
+
+uint32_t
+Materializer::AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err)
+{
+ EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
+ iter->reset (new EntityPersistentVariable (persistent_variable_sp));
+ uint32_t ret = AddStructMember(**iter);
+ (*iter)->SetOffset(ret);
+ return ret;
+}
+
+class EntityVariable : public Materializer::Entity
+{
+public:
+ EntityVariable (lldb::VariableSP &variable_sp) :
+ Entity(),
+ m_variable_sp(variable_sp)
+ {
+ Type *type = variable_sp->GetType();
+
+ assert(type);
+
+ if (type)
+ {
+ ClangASTType clang_type(type->GetClangAST(),
+ type->GetClangLayoutType());
+
+ SetSizeAndAlignmentFromType(clang_type);
+ }
+ }
+
+ virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+
+ virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+private:
+ lldb::VariableSP m_variable_sp;
+};
+
+uint32_t
+Materializer::AddVariable (lldb::VariableSP &variable_sp, Error &err)
+{
+ EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
+ iter->reset (new EntityVariable (variable_sp));
+ uint32_t ret = AddStructMember(**iter);
+ (*iter)->SetOffset(ret);
+ return ret;
+}
+
+class EntityResultVariable : public Materializer::Entity
+{
+public:
+ EntityResultVariable (const ClangASTType &type) :
+ Entity(),
+ m_type(type)
+ {
+ SetSizeAndAlignmentFromType(m_type);
+ }
+
+ virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+
+ virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+private:
+ ClangASTType m_type;
+};
+
+uint32_t
+Materializer::AddResultVariable (const ClangASTType &type, Error &err)
+{
+ EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
+ iter->reset (new EntityResultVariable (type));
+ uint32_t ret = AddStructMember(**iter);
+ (*iter)->SetOffset(ret);
+ return ret;
+}
+
+class EntitySymbol : public Materializer::Entity
+{
+public:
+ EntitySymbol (const Symbol &symbol) :
+ Entity(),
+ m_symbol(symbol)
+ {
+ // Hard-coding to maximum size of a symbol
+ m_size = 8;
+ m_alignment = 8;
+ }
+
+ virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+
+ virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+private:
+ Symbol m_symbol;
+};
+
+uint32_t
+Materializer::AddSymbol (const Symbol &symbol_sp, Error &err)
+{
+ EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
+ iter->reset (new EntitySymbol (symbol_sp));
+ uint32_t ret = AddStructMember(**iter);
+ (*iter)->SetOffset(ret);
+ return ret;
+}
+
+class EntityRegister : public Materializer::Entity
+{
+public:
+ EntityRegister (const RegisterInfo &register_info) :
+ Entity(),
+ m_register_info(register_info)
+ {
+ // Hard-coding alignment conservatively
+ m_size = m_register_info.byte_size;
+ m_alignment = m_register_info.byte_size;
+ }
+
+ virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+
+ virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+ {
+ }
+private:
+ RegisterInfo m_register_info;
+};
+
+uint32_t
+Materializer::AddRegister (const RegisterInfo &register_info, Error &err)
+{
+ EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
+ iter->reset (new EntityRegister (register_info));
+ uint32_t ret = AddStructMember(**iter);
+ (*iter)->SetOffset(ret);
+ return ret;
+}
+
+Materializer::Materializer () :
+ m_needs_dematerialize(Mutex::eMutexTypeNormal),
+ m_current_offset(0),
+ m_struct_alignment(8)
+{
+}
+
+
+Materializer::Dematerializer
+Materializer::Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &error)
+{
+ for (EntityUP &entity_up : m_entities)
+ {
+ entity_up->Materialize(frame_sp, map, process_address, error);
+
+ if (!error.Success())
+ return Dematerializer (*this, frame_sp, map, LLDB_INVALID_ADDRESS);
+ }
+
+ m_needs_dematerialize.Lock();
+
+ return Dematerializer (*this, frame_sp, map, process_address);
+}
+
+void
+Materializer::Dematerializer::Dematerialize (Error &error)
+{
+ lldb::StackFrameSP frame_sp = m_frame_wp.lock();
+
+ if (!frame_sp)
+ {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Couldn't dematerialize: frame is gone");
+ }
+ else
+ {
+ for (EntityUP &entity_up : m_materializer.m_entities)
+ {
+ entity_up->Dematerialize (frame_sp, m_map, m_process_address, error);
+
+ if (!error.Success())
+ break;
+ }
+ }
+
+ m_materializer.m_needs_dematerialize.Unlock();
+}