[Lldb-commits] [lldb] r142936 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/IRForTarget.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp
Sean Callanan
scallanan at apple.com
Tue Oct 25 11:36:40 PDT 2011
Author: spyffe
Date: Tue Oct 25 13:36:40 2011
New Revision: 142936
URL: http://llvm.org/viewvc/llvm-project?rev=142936&view=rev
Log:
Improved handling of static data in the expression
parser. Now expression like the following work as
expected:
-
(lldb) expr struct { int a; int b; } $blah = { 10, 20 }
<no result>
(lldb) expr $blah
(<anonymous struct at Parse:6:5>) $blah = {
(int) a = 10
(int) b = 20
}
-
Now the IRForTarget subsystem knows how to handle
static initializers of various composite types.
Also removed an unnecessary parameter from
ClangExpressionDeclMap::GetFunctionInfo.
Modified:
lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
lldb/trunk/include/lldb/Expression/IRForTarget.h
lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
lldb/trunk/source/Expression/IRForTarget.cpp
Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=142936&r1=142935&r2=142936&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Tue Oct 25 13:36:40 2011
@@ -293,10 +293,6 @@
/// The parsed Decl for the Function, as generated by ClangASTSource
/// on ClangExpressionDeclMap's behalf.
///
- /// @param[out] value
- /// A pointer to the address where a Value for the function's address
- /// can be stored. IRForTarget typically places a ConstantExpr here.
- ///
/// @param[out] ptr
/// The absolute address of the function in the target.
///
@@ -305,7 +301,6 @@
//------------------------------------------------------------------
bool
GetFunctionInfo (const clang::NamedDecl *decl,
- llvm::Value**& value,
uint64_t &ptr);
//------------------------------------------------------------------
Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=142936&r1=142935&r2=142936&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRForTarget.h (original)
+++ lldb/trunk/include/lldb/Expression/IRForTarget.h Tue Oct 25 13:36:40 2011
@@ -27,6 +27,7 @@
class Instruction;
class Module;
class StoreInst;
+ class TargetData;
class Type;
class Value;
}
@@ -432,6 +433,34 @@
//------------------------------------------------------------------
//------------------------------------------------------------------
+ /// Write an initializer to a memory array of assumed sufficient
+ /// size.
+ ///
+ /// @param[in] data
+ /// A pointer to the data to write to.
+ ///
+ /// @param[in] initializer
+ /// The initializer itself.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaterializeInitializer (uint8_t *data, llvm::Constant *initializer);
+
+ //------------------------------------------------------------------
+ /// Move an internal variable into the static allocation section.
+ ///
+ /// @param[in] global_variable
+ /// The variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaterializeInternalVariable (llvm::GlobalVariable *global_variable);
+
+ //------------------------------------------------------------------
/// Handle a single externally-defined variable
///
/// @param[in] value
@@ -578,6 +607,7 @@
lldb_private::ConstString m_result_name; ///< The name of the result variable ($0, $1, ...)
lldb_private::TypeFromParser m_result_type; ///< The type of the result variable.
llvm::Module *m_module; ///< The module being processed, or NULL if that has not been determined yet.
+ std::auto_ptr<llvm::TargetData> m_target_data; ///< The target data for the module being processed, or NULL if there is no module.
lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls
StaticDataAllocator *m_data_allocator; ///< If non-NULL, the allocator to use for constant strings
llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type
Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=142936&r1=142935&r2=142936&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Oct 25 13:36:40 2011
@@ -612,7 +612,6 @@
ClangExpressionDeclMap::GetFunctionInfo
(
const NamedDecl *decl,
- llvm::Value**& value,
uint64_t &ptr
)
{
@@ -624,7 +623,6 @@
// We know m_parser_vars is valid since we searched for the variable by
// its NamedDecl
- value = &entity_sp->m_parser_vars->m_llvm_value;
ptr = entity_sp->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
return true;
Modified: lldb/trunk/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=142936&r1=142935&r2=142936&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRForTarget.cpp (original)
+++ lldb/trunk/source/Expression/IRForTarget.cpp Tue Oct 25 13:36:40 2011
@@ -218,11 +218,10 @@
// Find the address of the function.
clang::NamedDecl *fun_decl = DeclForGlobal (fun);
- Value **fun_value_ptr = NULL;
if (fun_decl)
{
- if (!m_decl_map->GetFunctionInfo (fun_decl, fun_value_ptr, fun_addr))
+ if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
{
lldb_private::ConstString alternate_mangling_const_str;
bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr);
@@ -242,8 +241,6 @@
if (!found_it)
{
- fun_value_ptr = NULL;
-
if (log)
{
if (alternate_mangling_const_str)
@@ -1407,6 +1404,96 @@
return true;
}
+bool
+IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
+{
+ if (!initializer)
+ return true;
+
+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log && log->GetVerbose())
+ log->Printf(" MaterializeInitializer(%p, %s)", data, PrintValue(initializer).c_str());
+
+ Type *initializer_type = initializer->getType();
+
+ if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer))
+ {
+ memcpy (data, int_initializer->getValue().getRawData(), m_target_data->getTypeStoreSize(initializer_type));
+ return true;
+ }
+ else if (ConstantArray *array_initializer = dyn_cast<ConstantArray>(initializer))
+ {
+ if (array_initializer->isString())
+ {
+ std::string array_initializer_string = array_initializer->getAsString();
+ memcpy (data, array_initializer_string.c_str(), m_target_data->getTypeStoreSize(initializer_type));
+ }
+ else
+ {
+ ArrayType *array_initializer_type = array_initializer->getType();
+ Type *array_element_type = array_initializer_type->getElementType();
+
+ size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
+
+ for (int i = 0; i < array_initializer->getNumOperands(); ++i)
+ {
+ if (!MaterializeInitializer(data + (i * element_size), array_initializer->getOperand(i)))
+ return false;
+ }
+ }
+ return true;
+ }
+ else if (ConstantStruct *struct_initializer = dyn_cast<ConstantStruct>(initializer))
+ {
+ StructType *struct_initializer_type = struct_initializer->getType();
+ const StructLayout *struct_layout = m_target_data->getStructLayout(struct_initializer_type);
+
+ for (int i = 0;
+ i < struct_initializer->getNumOperands();
+ ++i)
+ {
+ if (!MaterializeInitializer(data + struct_layout->getElementOffset(i), struct_initializer->getOperand(i)))
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool
+IRForTarget::MaterializeInternalVariable (GlobalVariable *global_variable)
+{
+ if (GlobalVariable::isExternalLinkage(global_variable->getLinkage()))
+ return false;
+
+ uint64_t offset = m_data_allocator->GetStream().GetSize();
+
+ llvm::Type *variable_type = global_variable->getType();
+
+ Constant *initializer = global_variable->getInitializer();
+
+ llvm::Type *initializer_type = initializer->getType();
+
+ size_t size = m_target_data->getTypeAllocSize(initializer_type);
+
+ lldb_private::DataBufferHeap data(size, '\0');
+
+ if (initializer)
+ if (!MaterializeInitializer(data.GetBytes(), initializer))
+ return false;
+
+ m_data_allocator->GetStream().Write(data.GetBytes(), data.GetByteSize());
+
+ Constant *new_pointer = BuildRelocation(variable_type, offset);
+
+ global_variable->replaceAllUsesWith(new_pointer);
+
+ global_variable->eraseFromParent();
+
+ return true;
+}
+
// This function does not report errors; its callers are responsible.
bool
IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
@@ -1431,6 +1518,9 @@
}
else if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(llvm_value_ptr))
{
+ if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
+ return MaterializeInternalVariable(global_variable);
+
clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
if (!named_decl)
@@ -2211,42 +2301,47 @@
}
if (log)
- log->Printf(" \"%s\" [\"%s\"] (\"%s\") placed at %lld",
- value->getName().str().c_str(),
+ log->Printf(" \"%s\" (\"%s\") placed at %lld",
name.GetCString(),
- PrintValue(value, true).c_str(),
+ decl->getNameAsString().c_str(),
offset);
ConstantInt *offset_int(ConstantInt::get(offset_type, offset, true));
GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", FirstEntryInstruction);
- Value *replacement = NULL;
-
- // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in cases where the result
- // variable is an rvalue, we have to synthesize a dereference of the appropriate structure
- // entry in order to produce the static variable that the AST thinks it is accessing.
- if (name == m_result_name && !m_result_is_pointer)
+ if (value)
{
- BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType()->getPointerTo(), "", FirstEntryInstruction);
-
- LoadInst *load = new LoadInst(bit_cast, "", FirstEntryInstruction);
+ Value *replacement = NULL;
- replacement = load;
- }
- else
- {
- BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", FirstEntryInstruction);
-
- replacement = bit_cast;
- }
+ if (log)
+ log->Printf(" Replacing [%s]", PrintValue(value).c_str());
- if (Constant *constant = dyn_cast<Constant>(value))
- UnfoldConstant(constant, replacement, FirstEntryInstruction);
- else
- value->replaceAllUsesWith(replacement);
-
- if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
- var->eraseFromParent();
+ // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in cases where the result
+ // variable is an rvalue, we have to synthesize a dereference of the appropriate structure
+ // entry in order to produce the static variable that the AST thinks it is accessing.
+ if (name == m_result_name && !m_result_is_pointer)
+ {
+ BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType()->getPointerTo(), "", FirstEntryInstruction);
+
+ LoadInst *load = new LoadInst(bit_cast, "", FirstEntryInstruction);
+
+ replacement = load;
+ }
+ else
+ {
+ BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", FirstEntryInstruction);
+
+ replacement = bit_cast;
+ }
+
+ if (Constant *constant = dyn_cast<Constant>(value))
+ UnfoldConstant(constant, replacement, FirstEntryInstruction);
+ else
+ value->replaceAllUsesWith(replacement);
+
+ if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
+ var->eraseFromParent();
+ }
}
if (log)
@@ -2321,6 +2416,7 @@
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
m_module = &llvm_module;
+ m_target_data.reset(new TargetData(m_module));
Function* function = m_module->getFunction(StringRef(m_func_name.c_str()));
@@ -2343,6 +2439,18 @@
return false;
}
+ if (log)
+ {
+ std::string s;
+ raw_string_ostream oss(s);
+
+ m_module->print(oss, NULL);
+
+ oss.flush();
+
+ log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
+ }
+
llvm::Type *intptr_ty = Type::getInt8Ty(m_module->getContext());
m_reloc_placeholder = new llvm::GlobalVariable((*m_module),
More information about the lldb-commits
mailing list