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

llvm-svn: 110777
This commit is contained in:
Sean Callanan
2010-08-11 03:57:18 +00:00
parent 00012c869f
commit 2235f32bbd
12 changed files with 447 additions and 67 deletions

View File

@@ -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()
@@ -82,6 +83,31 @@ ClangExpressionDeclMap::GetIndexForDecl (uint32_t &index,
// 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,
@@ -400,35 +426,42 @@ ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
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 @@ ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
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 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
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);
@@ -823,6 +905,20 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
}
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,