Implemented a feature where the expression parser
can avoid running the code in the target if the
expression's result is known and the expression
has no side effects.

Right now this feature is quite conservative in
its guess about side effects, and it only computes
integer results, but the machinery to make it more
sophisticated is there.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@121952 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index be6d709..302ebf8 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -20,6 +20,7 @@
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/Expression/ClangASTSource.h"
 #include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Symbol/ClangASTContext.h"
@@ -121,6 +122,78 @@
     return m_struct_vars->m_result_name;
 }
 
+lldb::ClangExpressionVariableSP
+ClangExpressionDeclMap::BuildIntegerVariable (const ConstString &name,
+                                              lldb_private::TypeFromParser type,
+                                              const llvm::APInt& value)
+{
+    assert (m_parser_vars.get());
+
+    
+    clang::ASTContext *context(m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
+    
+    TypeFromUser user_type(ClangASTContext::CopyType(context, 
+                                                     type.GetASTContext(),
+                                                     type.GetOpaqueQualType()),
+                           context);
+    
+    DataBufferHeap *heap_data_buf = new DataBufferHeap(ClangASTType::GetClangTypeBitWidth(user_type.GetASTContext(),
+                                                                                          user_type.GetOpaqueQualType()) / 8,
+                                                       '\0');
+    
+    DataBufferSP data_sp(heap_data_buf);
+    
+    uint64_t value64 = value.getLimitedValue();
+    
+    ByteOrder byte_order = m_parser_vars->m_exe_ctx->process->GetByteOrder();
+    
+    size_t num_val_bytes = sizeof(value64);
+    size_t num_data_bytes = heap_data_buf->GetByteSize();
+    
+    size_t num_bytes = num_val_bytes;
+    if (num_bytes > num_data_bytes)
+        num_bytes = num_data_bytes;
+    
+    uint8_t *data_bytes = heap_data_buf->GetBytes();
+    
+    for (off_t byte_idx = 0;
+         byte_idx < num_bytes;
+         ++byte_idx)
+    {
+        uint64_t shift = byte_idx * 8;
+        uint64_t mask = 0xffll << shift;
+        uint8_t cur_byte = (uint8_t)((value64 & mask) >> shift);
+        
+        switch (byte_order)
+        {
+        case eByteOrderBig:
+            //                    High         Low
+            // Original:         |AABBCCDDEEFFGGHH|
+            // Target:                   |EEFFGGHH|
+            
+            data_bytes[num_data_bytes - (1 + byte_idx)] = cur_byte;
+            break;
+        case eByteOrderLittle:
+            // Target:                   |HHGGFFEE|
+            data_bytes[byte_idx] = cur_byte;
+            break;
+        default:
+            return lldb::ClangExpressionVariableSP();    
+        }
+    }
+    
+    ValueObjectSP valobj_sp(new ValueObjectConstResult(user_type.GetASTContext(),
+                                                       user_type.GetOpaqueQualType(),
+                                                       name,
+                                                       data_sp,
+                                                       m_parser_vars->m_exe_ctx->process->GetByteOrder(), 
+                                                       m_parser_vars->m_exe_ctx->process->GetAddressByteSize()));
+    
+    ClangExpressionVariableSP var_sp(new ClangExpressionVariable(valobj_sp));
+    
+    return var_sp;
+}
+
 bool 
 ClangExpressionDeclMap::AddPersistentVariable 
 (