[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