forked from OSchip/llvm-project
Added functionality to dematerialize values that were
used by the JIT compiled expression, including the result of the expression. Also added a new class, ASTType, which encapsulates an opaque Clang type and its associated AST context. Refactored ClangExpressionDeclMap to use ASTTypes, significantly reducing the possibility of mixups of types from different AST contexts. llvm-svn: 108965
This commit is contained in:
parent
e706501975
commit
1d18066411
|
@ -21,6 +21,7 @@
|
|||
// Project includes
|
||||
#include "lldb/Core/ClangForward.h"
|
||||
#include "lldb/Core/Value.h"
|
||||
#include "lldb/Symbol/ASTType.h"
|
||||
|
||||
namespace clang {
|
||||
class DeclarationName;
|
||||
|
@ -54,6 +55,7 @@ public:
|
|||
const clang::NamedDecl *decl,
|
||||
std::string &name,
|
||||
void *type,
|
||||
clang::ASTContext *ast_context,
|
||||
size_t size,
|
||||
off_t alignment);
|
||||
bool DoStructLayout ();
|
||||
|
@ -69,20 +71,27 @@ public:
|
|||
Value *GetValueForIndex (uint32_t index);
|
||||
|
||||
// Interface for CommandObjectExpression
|
||||
lldb::addr_t Materialize(ExecutionContext *exe_ctx,
|
||||
Error &error);
|
||||
bool Materialize(ExecutionContext *exe_ctx,
|
||||
lldb::addr_t &struct_address,
|
||||
Error &error);
|
||||
|
||||
bool Dematerialize(ExecutionContext *exe_ctx,
|
||||
lldb_private::Value &result_value,
|
||||
Error &error);
|
||||
|
||||
// Interface for ClangASTSource
|
||||
void GetDecls (NameSearchContext &context,
|
||||
const char *name);
|
||||
protected:
|
||||
private:
|
||||
typedef TaggedASTType<0> TypeFromParser;
|
||||
typedef TaggedASTType<1> TypeFromUser;
|
||||
|
||||
struct Tuple
|
||||
{
|
||||
const clang::NamedDecl *m_decl;
|
||||
clang::ASTContext *m_ast_context;
|
||||
void *m_orig_type;
|
||||
Value *m_value; /* owned by ClangExpressionDeclMap */
|
||||
TypeFromParser m_parser_type;
|
||||
TypeFromUser m_user_type;
|
||||
lldb_private::Value *m_value; /* owned by ClangExpressionDeclMap */
|
||||
};
|
||||
|
||||
struct StructMember
|
||||
|
@ -90,7 +99,7 @@ private:
|
|||
const clang::NamedDecl *m_decl;
|
||||
llvm::Value *m_value;
|
||||
std::string m_name;
|
||||
void *m_type;
|
||||
TypeFromParser m_parser_type;
|
||||
off_t m_offset;
|
||||
size_t m_size;
|
||||
off_t m_alignment;
|
||||
|
@ -109,29 +118,35 @@ private:
|
|||
off_t m_struct_alignment;
|
||||
size_t m_struct_size;
|
||||
bool m_struct_laid_out;
|
||||
lldb::addr_t m_allocated_area;
|
||||
lldb::addr_t m_materialized_location;
|
||||
|
||||
Variable *FindVariableInScope(const SymbolContext &sym_ctx,
|
||||
const char *name,
|
||||
void *type = NULL,
|
||||
clang::ASTContext *ast_context = NULL);
|
||||
TypeFromUser *type = NULL);
|
||||
|
||||
Value *GetVariableValue(ExecutionContext &exe_ctx,
|
||||
Variable *var,
|
||||
clang::ASTContext *target_ast_context = NULL,
|
||||
void **opaque_type = NULL,
|
||||
clang::ASTContext **found_ast_context = NULL);
|
||||
clang::ASTContext *parser_ast_context,
|
||||
TypeFromUser *found_type = NULL,
|
||||
TypeFromParser *parser_type = NULL);
|
||||
|
||||
void AddOneVariable(NameSearchContext &context, Variable *var);
|
||||
void AddOneFunction(NameSearchContext &context, Function *fun);
|
||||
|
||||
bool MaterializeOneVariable(ExecutionContext &exe_ctx,
|
||||
const SymbolContext &sym_ctx,
|
||||
const char *name,
|
||||
void *type,
|
||||
clang::ASTContext *ast_context,
|
||||
lldb::addr_t addr,
|
||||
Error &err);
|
||||
// Set D to dematerialize instead
|
||||
bool DoMaterialize (bool dematerialize,
|
||||
ExecutionContext *exe_ctx,
|
||||
lldb_private::Value *result_value, /* must be non-NULL if D is set */
|
||||
Error &err);
|
||||
|
||||
bool DoMaterializeOneVariable(bool dematerialize,
|
||||
ExecutionContext &exe_ctx,
|
||||
const SymbolContext &sym_ctx,
|
||||
const char *name,
|
||||
TypeFromUser type,
|
||||
lldb::addr_t addr,
|
||||
Error &err);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
//===-- ASTType.h -----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace clang
|
||||
{
|
||||
class ASTContext;
|
||||
}
|
||||
|
||||
namespace lldb_private
|
||||
{
|
||||
|
||||
class ASTTypeBase
|
||||
{
|
||||
protected:
|
||||
ASTTypeBase (void *type, clang::ASTContext *ast_context) :
|
||||
m_type(type),
|
||||
m_ast_context(ast_context)
|
||||
{
|
||||
}
|
||||
|
||||
ASTTypeBase (const ASTTypeBase &tw) :
|
||||
m_type(tw.m_type),
|
||||
m_ast_context(tw.m_ast_context)
|
||||
{
|
||||
}
|
||||
|
||||
ASTTypeBase () :
|
||||
m_type(0),
|
||||
m_ast_context(0)
|
||||
{
|
||||
}
|
||||
|
||||
~ASTTypeBase();
|
||||
|
||||
ASTTypeBase &operator= (const ASTTypeBase &atb)
|
||||
{
|
||||
m_type = atb.m_type;
|
||||
m_ast_context = atb.m_ast_context;
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
void *GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
clang::ASTContext *GetASTContext() const
|
||||
{
|
||||
return m_ast_context;
|
||||
}
|
||||
|
||||
private:
|
||||
void *m_type;
|
||||
clang::ASTContext *m_ast_context;
|
||||
};
|
||||
|
||||
class ASTType : public ASTTypeBase
|
||||
{
|
||||
public:
|
||||
ASTType (void *type, clang::ASTContext *ast_context) :
|
||||
ASTTypeBase(type, ast_context) { }
|
||||
|
||||
ASTType (const ASTType &at) :
|
||||
ASTTypeBase(at) { }
|
||||
|
||||
ASTType () :
|
||||
ASTTypeBase() { }
|
||||
|
||||
~ASTType();
|
||||
|
||||
ASTType &operator= (const ASTType &at)
|
||||
{
|
||||
ASTTypeBase::operator= (at);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// For cases in which there are multiple classes of types that are not
|
||||
// interchangeable, to allow static type checking.
|
||||
template <unsigned int C> class TaggedASTType : public ASTTypeBase
|
||||
{
|
||||
public:
|
||||
TaggedASTType (void *type, clang::ASTContext *ast_context) :
|
||||
ASTTypeBase(type, ast_context) { }
|
||||
|
||||
TaggedASTType (const TaggedASTType<C> &tw) :
|
||||
ASTTypeBase(tw) { }
|
||||
|
||||
TaggedASTType () :
|
||||
ASTTypeBase() { }
|
||||
|
||||
~TaggedASTType() { }
|
||||
|
||||
TaggedASTType<C> &operator= (const TaggedASTType<C> &tw)
|
||||
{
|
||||
ASTTypeBase::operator= (tw);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
// Project includes
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/Core/ClangForward.h"
|
||||
|
||||
#include "lldb/Symbol/ASTType.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
|
|
|
@ -335,6 +335,8 @@
|
|||
49D7072911B5AD11001AD875 /* ClangASTSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; };
|
||||
49DA743011DE6A5A006AEF7E /* IRToDWARF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */; };
|
||||
49DA743511DE6BB2006AEF7E /* IRToDWARF.h in Headers */ = {isa = PBXBuildFile; fileRef = 49DA743411DE6BB2006AEF7E /* IRToDWARF.h */; };
|
||||
49E45FAA11F660DC008F7B28 /* ASTType.h in Headers */ = {isa = PBXBuildFile; fileRef = 49E45FA911F660DC008F7B28 /* ASTType.h */; };
|
||||
49E45FAF11F660FE008F7B28 /* ASTType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49E45FAD11F660FE008F7B28 /* ASTType.cpp */; };
|
||||
49F1A74611B3388F003ED505 /* ClangExpressionDeclMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */; };
|
||||
49F1A74A11B338AE003ED505 /* ClangExpressionDeclMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 49F1A74911B338AE003ED505 /* ClangExpressionDeclMap.h */; };
|
||||
4C08CDE811C81EF8001610A8 /* ThreadSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C08CDE711C81EF8001610A8 /* ThreadSpec.cpp */; };
|
||||
|
@ -910,6 +912,8 @@
|
|||
49D7072811B5AD11001AD875 /* ClangASTSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTSource.cpp; path = source/Expression/ClangASTSource.cpp; sourceTree = "<group>"; };
|
||||
49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRToDWARF.cpp; path = source/Expression/IRToDWARF.cpp; sourceTree = "<group>"; };
|
||||
49DA743411DE6BB2006AEF7E /* IRToDWARF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IRToDWARF.h; path = include/lldb/Expression/IRToDWARF.h; sourceTree = "<group>"; };
|
||||
49E45FA911F660DC008F7B28 /* ASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTType.h; path = include/lldb/Symbol/ASTType.h; sourceTree = "<group>"; };
|
||||
49E45FAD11F660FE008F7B28 /* ASTType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTType.cpp; path = source/Symbol/ASTType.cpp; sourceTree = "<group>"; };
|
||||
49EC3E98118F90AC00B1265E /* ThreadPlanCallFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanCallFunction.cpp; path = source/Target/ThreadPlanCallFunction.cpp; sourceTree = "<group>"; };
|
||||
49EC3E9C118F90D400B1265E /* ThreadPlanCallFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanCallFunction.h; path = include/lldb/Target/ThreadPlanCallFunction.h; sourceTree = "<group>"; };
|
||||
49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExpressionDeclMap.cpp; path = source/Expression/ClangExpressionDeclMap.cpp; sourceTree = "<group>"; };
|
||||
|
@ -1665,6 +1669,8 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
AF94005711C03F6500085DB9 /* SymbolVendor.cpp */,
|
||||
49E45FA911F660DC008F7B28 /* ASTType.h */,
|
||||
49E45FAD11F660FE008F7B28 /* ASTType.cpp */,
|
||||
26BC7C5510F1B6E900F91463 /* Block.h */,
|
||||
26BC7F1310F1B8EC00F91463 /* Block.cpp */,
|
||||
26BC7C5610F1B6E900F91463 /* ClangASTContext.h */,
|
||||
|
@ -2195,6 +2201,7 @@
|
|||
49307AB211DEA4F20081F992 /* IRForTarget.h in Headers */,
|
||||
4C5DBBC911E3FEC60035160F /* CommandObjectCommands.h in Headers */,
|
||||
26D27CA011ED3A4E0024D721 /* ELFHeader.h in Headers */,
|
||||
49E45FAA11F660DC008F7B28 /* ASTType.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -2648,6 +2655,7 @@
|
|||
49307AAE11DEA4D90081F992 /* IRForTarget.cpp in Sources */,
|
||||
4C5DBBC811E3FEC60035160F /* CommandObjectCommands.cpp in Sources */,
|
||||
26D27C9F11ED3A4E0024D721 /* ELFHeader.cpp in Sources */,
|
||||
49E45FAF11F660FE008F7B28 /* ASTType.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -305,10 +305,9 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream
|
|||
}
|
||||
|
||||
Error err;
|
||||
|
||||
lldb::addr_t struct_address = expr_decl_map.Materialize(&m_exe_ctx, err);
|
||||
lldb::addr_t struct_address;
|
||||
|
||||
if (struct_address == LLDB_INVALID_ADDRESS)
|
||||
if (!expr_decl_map.Materialize(&m_exe_ctx, struct_address, err))
|
||||
{
|
||||
error_stream.Printf ("Couldn't materialize struct: %s\n", err.AsCString("unknown error"));
|
||||
return false;
|
||||
|
|
|
@ -28,9 +28,10 @@
|
|||
#include "lldb/Symbol/TypeList.h"
|
||||
#include "lldb/Symbol/Variable.h"
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/StackFrame.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
using namespace lldb_private;
|
||||
using namespace clang;
|
||||
|
@ -83,7 +84,8 @@ bool
|
|||
ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value,
|
||||
const clang::NamedDecl *decl,
|
||||
std::string &name,
|
||||
void *type,
|
||||
void *parser_type,
|
||||
clang::ASTContext *parser_ast_context,
|
||||
size_t size,
|
||||
off_t alignment)
|
||||
{
|
||||
|
@ -101,13 +103,13 @@ ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value,
|
|||
|
||||
StructMember member;
|
||||
|
||||
member.m_value = value;
|
||||
member.m_decl = decl;
|
||||
member.m_name = name;
|
||||
member.m_type = type;
|
||||
member.m_offset = 0;
|
||||
member.m_size = size;
|
||||
member.m_alignment = alignment;
|
||||
member.m_value = value;
|
||||
member.m_decl = decl;
|
||||
member.m_name = name;
|
||||
member.m_parser_type = TypeFromParser(parser_type, parser_ast_context);
|
||||
member.m_offset = 0;
|
||||
member.m_size = size;
|
||||
member.m_alignment = alignment;
|
||||
|
||||
m_members.push_back(member);
|
||||
|
||||
|
@ -181,7 +183,7 @@ ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
|
|||
}
|
||||
|
||||
// Interface for DwarfExpression
|
||||
Value
|
||||
lldb_private::Value
|
||||
*ClangExpressionDeclMap::GetValueForIndex (uint32_t index)
|
||||
{
|
||||
if (index >= m_tuples.size ())
|
||||
|
@ -191,8 +193,33 @@ Value
|
|||
}
|
||||
|
||||
// Interface for CommandObjectExpression
|
||||
lldb::addr_t
|
||||
ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx, Error &err)
|
||||
|
||||
bool
|
||||
ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
|
||||
lldb::addr_t &struct_address,
|
||||
Error &err)
|
||||
{
|
||||
bool result = DoMaterialize(false, exe_ctx, NULL, err);
|
||||
|
||||
if (result)
|
||||
struct_address = m_materialized_location;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
|
||||
lldb_private::Value &result_value,
|
||||
Error &err)
|
||||
{
|
||||
return DoMaterialize(true, exe_ctx, &result_value, err);
|
||||
}
|
||||
|
||||
bool
|
||||
ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
|
||||
ExecutionContext *exe_ctx,
|
||||
lldb_private::Value *result_value,
|
||||
Error &err)
|
||||
{
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
||||
|
||||
|
@ -202,12 +229,6 @@ ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx, Error &err)
|
|||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (m_materialized_location)
|
||||
{
|
||||
exe_ctx->process->DeallocateMemory(m_materialized_location);
|
||||
m_materialized_location = 0;
|
||||
}
|
||||
|
||||
if (!exe_ctx)
|
||||
{
|
||||
err.SetErrorString("Received null execution context");
|
||||
|
@ -216,24 +237,33 @@ ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx, Error &err)
|
|||
|
||||
const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
|
||||
|
||||
StructMemberIterator iter;
|
||||
|
||||
lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
|
||||
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
|
||||
err);
|
||||
|
||||
if (mem == LLDB_INVALID_ADDRESS)
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
m_materialized_location = mem;
|
||||
|
||||
lldb::addr_t aligned_mem = mem;
|
||||
|
||||
if (aligned_mem % m_struct_alignment)
|
||||
if (!dematerialize)
|
||||
{
|
||||
aligned_mem += (m_struct_alignment - (aligned_mem % m_struct_alignment));
|
||||
if (m_materialized_location)
|
||||
{
|
||||
exe_ctx->process->DeallocateMemory(m_materialized_location);
|
||||
m_materialized_location = 0;
|
||||
}
|
||||
|
||||
lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
|
||||
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
|
||||
err);
|
||||
|
||||
if (mem == LLDB_INVALID_ADDRESS)
|
||||
return false;
|
||||
|
||||
m_allocated_area = mem;
|
||||
}
|
||||
|
||||
m_materialized_location = m_allocated_area;
|
||||
|
||||
if (m_materialized_location % m_struct_alignment)
|
||||
{
|
||||
m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
|
||||
}
|
||||
|
||||
StructMemberIterator iter;
|
||||
|
||||
for (iter = m_members.begin();
|
||||
iter != m_members.end();
|
||||
++iter)
|
||||
|
@ -251,23 +281,122 @@ ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx, Error &err)
|
|||
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.GetType()),
|
||||
context);
|
||||
|
||||
result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetType());
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Tuple &tuple(m_tuples[tuple_index]);
|
||||
|
||||
if (!MaterializeOneVariable(*exe_ctx, sym_ctx, iter->m_name.c_str(), tuple.m_orig_type, tuple.m_ast_context, aligned_mem + iter->m_offset, err))
|
||||
if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, iter->m_name.c_str(), tuple.m_user_type, m_materialized_location + iter->m_offset, err))
|
||||
return false;
|
||||
}
|
||||
|
||||
return aligned_mem;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
|
||||
ExecutionContext &exe_ctx,
|
||||
const SymbolContext &sym_ctx,
|
||||
const char *name,
|
||||
TypeFromUser type,
|
||||
lldb::addr_t addr,
|
||||
Error &err)
|
||||
{
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
||||
|
||||
Variable *var = FindVariableInScope(sym_ctx, name, &type);
|
||||
|
||||
if (!var)
|
||||
{
|
||||
err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetType());
|
||||
|
||||
std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
|
||||
var,
|
||||
type.GetASTContext()));
|
||||
|
||||
if (!location_value.get())
|
||||
{
|
||||
err.SetErrorStringWithFormat("Couldn't get value for %s", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
|
||||
{
|
||||
lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
|
||||
|
||||
size_t bit_size = ClangASTContext::GetTypeBitSize(type.GetASTContext(), type.GetType());
|
||||
size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
|
||||
|
||||
DataBufferHeap data;
|
||||
data.SetByteSize(byte_size);
|
||||
|
||||
lldb::addr_t src_addr;
|
||||
lldb::addr_t dest_addr;
|
||||
|
||||
if (dematerialize)
|
||||
{
|
||||
src_addr = addr;
|
||||
dest_addr = value_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_addr = value_addr;
|
||||
dest_addr = addr;
|
||||
}
|
||||
|
||||
Error error;
|
||||
if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
|
||||
{
|
||||
err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
|
||||
{
|
||||
err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamString ss;
|
||||
|
||||
location_value->Dump(&ss);
|
||||
|
||||
err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Variable*
|
||||
ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
|
||||
const char *name,
|
||||
void *type,
|
||||
clang::ASTContext *ast_context)
|
||||
TypeFromUser *type)
|
||||
{
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
||||
|
||||
|
@ -319,9 +448,9 @@ ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
|
|||
if (!type)
|
||||
return var.get();
|
||||
|
||||
if (ast_context == var->GetType()->GetClangAST())
|
||||
if (type->GetASTContext() == var->GetType()->GetClangAST())
|
||||
{
|
||||
if (!ClangASTContext::AreTypesSame(ast_context, type, var->GetType()->GetOpaqueClangQualType()))
|
||||
if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type, var->GetType()->GetOpaqueClangQualType()))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
@ -357,9 +486,9 @@ ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
|
|||
if (!type)
|
||||
return var.get();
|
||||
|
||||
if (ast_context == var->GetType()->GetClangAST())
|
||||
if (type->GetASTContext() == var->GetType()->GetClangAST())
|
||||
{
|
||||
if (!ClangASTContext::AreTypesSame(ast_context, type, var->GetType()->GetOpaqueClangQualType()))
|
||||
if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetType(), var->GetType()->GetOpaqueClangQualType()))
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
|
@ -375,75 +504,6 @@ ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
ClangExpressionDeclMap::MaterializeOneVariable(ExecutionContext &exe_ctx,
|
||||
const SymbolContext &sym_ctx,
|
||||
const char *name,
|
||||
void *type,
|
||||
clang::ASTContext *ast_context,
|
||||
lldb::addr_t addr,
|
||||
Error &err)
|
||||
{
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
||||
|
||||
Variable *var = FindVariableInScope(sym_ctx, name, type, ast_context);
|
||||
|
||||
if (!var)
|
||||
{
|
||||
err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
log->Printf("Materializing %s with type %p", name, type);
|
||||
|
||||
std::auto_ptr<Value> location_value(GetVariableValue(exe_ctx,
|
||||
var,
|
||||
ast_context));
|
||||
|
||||
if (!location_value.get())
|
||||
{
|
||||
err.SetErrorStringWithFormat("Couldn't get value for %s", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
|
||||
{
|
||||
lldb::addr_t src_addr = location_value->GetScalar().ULongLong();
|
||||
|
||||
size_t bit_size = ClangASTContext::GetTypeBitSize(ast_context, type);
|
||||
size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
|
||||
|
||||
DataBufferHeap data;
|
||||
data.SetByteSize(byte_size);
|
||||
|
||||
Error error;
|
||||
if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
|
||||
{
|
||||
err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (exe_ctx.process->WriteMemory (addr, data.GetBytes(), byte_size, error) != byte_size)
|
||||
{
|
||||
err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamString ss;
|
||||
|
||||
location_value->Dump(&ss);
|
||||
|
||||
err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Interface for ClangASTSource
|
||||
void
|
||||
ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
|
||||
|
@ -483,9 +543,9 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
|
|||
Value *
|
||||
ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
|
||||
Variable *var,
|
||||
clang::ASTContext *target_ast_context,
|
||||
void **opaque_type,
|
||||
clang::ASTContext **found_ast_context)
|
||||
clang::ASTContext *parser_ast_context,
|
||||
TypeFromUser *user_type,
|
||||
TypeFromParser *parser_type)
|
||||
{
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
||||
|
||||
|
@ -542,8 +602,13 @@ ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
|
|||
|
||||
void *type_to_use;
|
||||
|
||||
if (target_ast_context)
|
||||
type_to_use = ClangASTContext::CopyType(target_ast_context, var_ast_context, var_opaque_type);
|
||||
if (parser_ast_context)
|
||||
{
|
||||
type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
|
||||
|
||||
if (parser_type)
|
||||
*parser_type = TypeFromParser(type_to_use, parser_ast_context);
|
||||
}
|
||||
else
|
||||
type_to_use = var_opaque_type;
|
||||
|
||||
|
@ -571,11 +636,8 @@ ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
|
|||
var_location->SetValueType(Value::eValueTypeLoadAddress);
|
||||
}
|
||||
|
||||
if (opaque_type)
|
||||
*opaque_type = var_opaque_type;
|
||||
|
||||
if (found_ast_context)
|
||||
*found_ast_context = var_ast_context;
|
||||
if (user_type)
|
||||
*user_type = TypeFromUser(var_opaque_type, var_ast_context);
|
||||
|
||||
return var_location.release();
|
||||
}
|
||||
|
@ -586,23 +648,23 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
|
|||
{
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
||||
|
||||
void *var_opaque_type = NULL;
|
||||
clang::ASTContext *var_ast_context = NULL;
|
||||
TypeFromUser ut;
|
||||
TypeFromParser pt;
|
||||
|
||||
Value *var_location = GetVariableValue(*m_exe_ctx,
|
||||
var,
|
||||
context.GetASTContext(),
|
||||
&var_opaque_type,
|
||||
&var_ast_context);
|
||||
&ut,
|
||||
&pt);
|
||||
|
||||
NamedDecl *var_decl = context.AddVarDecl(var_opaque_type);
|
||||
NamedDecl *var_decl = context.AddVarDecl(pt.GetType());
|
||||
|
||||
Tuple tuple;
|
||||
|
||||
tuple.m_decl = var_decl;
|
||||
tuple.m_value = var_location;
|
||||
tuple.m_orig_type = var_opaque_type;
|
||||
tuple.m_ast_context = var_ast_context;
|
||||
tuple.m_user_type = ut;
|
||||
tuple.m_parser_type = pt;
|
||||
|
||||
m_tuples.push_back(tuple);
|
||||
|
||||
|
@ -651,8 +713,7 @@ ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
|
|||
|
||||
tuple.m_decl = fun_decl;
|
||||
tuple.m_value = fun_location.release();
|
||||
tuple.m_orig_type = fun_opaque_type;
|
||||
tuple.m_ast_context = fun_ast_context;
|
||||
tuple.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);
|
||||
|
||||
m_tuples.push_back(tuple);
|
||||
|
||||
|
|
|
@ -93,12 +93,18 @@ IRForTarget::MaybeHandleVariable(Module &M,
|
|||
std::string name = named_decl->getName().str();
|
||||
|
||||
void *qual_type = NULL;
|
||||
clang::ASTContext *ast_context = NULL;
|
||||
|
||||
if (clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl))
|
||||
{
|
||||
qual_type = value_decl->getType().getAsOpaquePtr();
|
||||
ast_context = &value_decl->getASTContext();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
const llvm::Type *value_type = global_variable->getType();
|
||||
|
||||
size_t value_size = m_target_data->getTypeStoreSize(value_type);
|
||||
|
@ -108,6 +114,7 @@ IRForTarget::MaybeHandleVariable(Module &M,
|
|||
named_decl,
|
||||
name,
|
||||
qual_type,
|
||||
ast_context,
|
||||
value_size,
|
||||
value_alignment))
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
//===-- ASTType.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/Symbol/ASTType.h"
|
||||
|
||||
using namespace lldb_private;
|
||||
|
||||
ASTTypeBase::~ASTTypeBase()
|
||||
{
|
||||
}
|
||||
|
||||
ASTType::~ASTType()
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue