diff options
author | Sean Callanan <scallanan@apple.com> | 2011-10-25 18:36:40 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2011-10-25 18:36:40 +0000 |
commit | c70ed46dda73cd80b30e832103c14f8c68e85e0b (patch) | |
tree | 37c04b6cb39b3547d08263a35f231611e25f7803 /lldb/source | |
parent | afa155fb8879f77c40a73360b1215b65d7501aa9 (diff) | |
download | bcm5719-llvm-c70ed46dda73cd80b30e832103c14f8c68e85e0b.tar.gz bcm5719-llvm-c70ed46dda73cd80b30e832103c14f8c68e85e0b.zip |
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.
llvm-svn: 142936
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 170 |
2 files changed, 139 insertions, 33 deletions
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index fb8cc591297..5566091206f 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -612,7 +612,6 @@ bool ClangExpressionDeclMap::GetFunctionInfo ( const NamedDecl *decl, - llvm::Value**& value, uint64_t &ptr ) { @@ -624,7 +623,6 @@ ClangExpressionDeclMap::GetFunctionInfo // 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; diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index 50cd0cc2896..feac49284a7 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -218,11 +218,10 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun, // 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 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun, if (!found_it) { - fun_value_ptr = NULL; - if (log) { if (alternate_mangling_const_str) @@ -1407,6 +1404,96 @@ IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) 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 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr) } 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 @@ IRForTarget::ReplaceVariables (Function &llvm_function) } 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 @@ IRForTarget::runOnModule (Module &llvm_module) 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 @@ IRForTarget::runOnModule (Module &llvm_module) 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), |