Added support for persistent variables to the
expression parser.  It is now possible to type:

(lldb) expr int $i = 5; $i + 1
(int) 6
(lldb) expr $i + 2
(int) 7

The skeleton for automatic result variables is
also implemented.  The changes affect:

- the process, which now contains a 
  ClangPersistentVariables object that holds
  persistent variables associated with it
- the expression parser, which now uses
  the persistent variables during variable
  lookup
- TaggedASTType, where I loaded some commonly
  used tags into a header so that they are
  interchangeable between different clients of
  the class


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@110777 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index b50d68e..da4333c 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -19,6 +19,7 @@
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Expression/ClangASTSource.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Function.h"
@@ -36,17 +37,17 @@
 using namespace lldb_private;
 using namespace clang;
 
-ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx,
-                                               ClangPersistentVariables &persistent_vars) :
-    m_exe_ctx(exe_ctx),
-    m_persistent_vars(persistent_vars),
-    m_struct_laid_out(false),
+ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
+    m_exe_ctx(exe_ctx),    m_struct_laid_out(false),
     m_materialized_location(0)
 {
     if (exe_ctx && exe_ctx->frame)
         m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
     else
         m_sym_ctx = NULL;
+    
+    if (exe_ctx && exe_ctx->process)
+        m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
 }
 
 ClangExpressionDeclMap::~ClangExpressionDeclMap()
@@ -83,6 +84,31 @@
 // Interface for IRForTarget
 
 bool 
+ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl)
+{
+    clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
+    
+    const clang::VarDecl *var(dyn_cast<clang::VarDecl>(decl));
+    
+    if (!var)
+        return false;
+    
+    TypeFromUser user_type(ClangASTContext::CopyType(context, 
+                                                     &var->getASTContext(),
+                                                     var->getType().getAsOpaquePtr()),
+                            context);
+    
+    ConstString const_name(decl->getName().str().c_str());
+    
+    ClangPersistentVariable *pvar = m_persistent_vars->CreateVariable(const_name, user_type);
+    
+    if (!pvar)
+        return false;
+    
+    return true;
+}
+
+bool 
 ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value,
                                           const clang::NamedDecl *decl,
                                           std::string &name,
@@ -400,35 +426,42 @@
         
         if (!GetIndexForDecl(tuple_index, iter->m_decl)) 
         {
-            if (iter->m_name.find("___clang_expr_result") == std::string::npos)
+            if (iter->m_name[0] == '$')
+            {
+                if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err))
+                    return false;
+            }
+            else if (iter->m_name.find("___clang_expr_result") != std::string::npos)
+            {
+                if (log)
+                    log->Printf("Found special result variable %s", iter->m_name.c_str());
+                
+                if (dematerialize)
+                {
+                    clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext());
+                    
+                    if (!context)
+                    {
+                        err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); 
+                    }
+                    
+                    TypeFromUser copied_type(ClangASTContext::CopyType(context, 
+                                                                       iter->m_parser_type.GetASTContext(),
+                                                                       iter->m_parser_type.GetOpaqueQualType()),
+                                             context);
+                    
+                    result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType());
+                    
+                    result_value->SetValueType(Value::eValueTypeLoadAddress);
+                    result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset;
+                }
+            }
+            else
             {
                 err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str());
                 return false;
             }
             
-            if (log)
-                log->Printf("Found special result variable %s", iter->m_name.c_str());
-            
-            if (dematerialize)
-            {
-                clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext());
-                
-                if (!context)
-                {
-                    err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); 
-                }
-                
-                TypeFromUser copied_type(ClangASTContext::CopyType(context, 
-                                                                   iter->m_parser_type.GetASTContext(),
-                                                                   iter->m_parser_type.GetOpaqueQualType()),
-                                         context);
-                
-                result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType());
-                
-                result_value->SetValueType(Value::eValueTypeLoadAddress);
-                result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset;
-            }
-            
             continue;
         }
         
@@ -441,6 +474,50 @@
     return true;
 }
 
+bool
+ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
+                                                           ExecutionContext &exe_ctx,
+                                                           const char *name,
+                                                           lldb::addr_t addr,
+                                                           Error &err)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+
+    if (log)
+        log->Printf("Found persistent variable %s", name);
+    
+    ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name)));
+    
+    if (!pvar)
+    {
+        err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
+        return LLDB_INVALID_ADDRESS;
+    }
+    
+    size_t pvar_size = pvar->Size();
+    uint8_t *pvar_data = pvar->Data();                
+    Error error;
+    
+    if (dematerialize)
+    {
+        if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
+        {
+            err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
+            return false;
+        }
+    }
+    else 
+    {
+        if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
+        {
+            err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
+            return false;
+        }
+    }
+    
+    return true;
+}
+
 bool 
 ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
                                                  ExecutionContext &exe_ctx,
@@ -682,6 +759,11 @@
     if (var)
         AddOneVariable(context, var);
     
+    ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name)));
+    
+    if (pvar)
+        AddOneVariable(context, pvar);
+    
     /* Commented out pending resolution of a loop when the TagType is imported
     lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
     
@@ -824,6 +906,20 @@
 }
 
 void
+ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
+                                       ClangPersistentVariable *pvar)
+{
+    TypeFromUser user_type = pvar->Type();
+    
+    TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(), 
+                                                         user_type.GetASTContext(), 
+                                                         user_type.GetOpaqueQualType()),
+                               context.GetASTContext());
+    
+    (void)context.AddVarDecl(parser_type.GetOpaqueQualType());
+}
+
+void
 ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
                                        Function* fun,
                                        Symbol* symbol)