[Lldb-commits] [lldb] r143065 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRInterpreter.cpp

Sean Callanan scallanan at apple.com
Wed Oct 26 14:20:01 PDT 2011


Author: spyffe
Date: Wed Oct 26 16:20:00 2011
New Revision: 143065

URL: http://llvm.org/viewvc/llvm-project?rev=143065&view=rev
Log:
Extended the IR interpreter to handle the variables
"_cmd", "this", and "self".  These variables are handled
differently from all other external variables used by
the expression.  Other variables are used indirectly
through the $__lldb_arg operand; only _cmd, this, and
self are passed directly through the ABI.

There are two modifications:

 - I added a function to ClangExpressionDeclMap that
   retrives the value of one of these variables by name;
   and

 - I made IRInterpreter fetch these values when needed,
   and ensured that the proper level of indirection is
   used.

Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/IRInterpreter.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=143065&r1=143064&r2=143065&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Wed Oct 26 16:20:00 2011
@@ -441,6 +441,19 @@
     LookupDecl (clang::NamedDecl *decl);
     
     //------------------------------------------------------------------
+    /// [Used by IRInterpreter] Get the Value for "this", "self", or
+    ///   "_cmd".
+    ///
+    /// @param[in] name
+    ///     The name of the entity to be found.
+    ///
+    /// @return
+    ///     The value, or NULL.
+    //------------------------------------------------------------------
+    lldb_private::Value
+    GetSpecialValue (const ConstString &name);
+    
+    //------------------------------------------------------------------
     /// [Used by IRInterpreter] Returns true if the result is a
     ///   reference to data in the target, meaning it must be
     ///   dereferenced once more to get its data.

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=143065&r1=143064&r2=143065&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Wed Oct 26 16:20:00 2011
@@ -959,7 +959,12 @@
         if (!expr_var_sp->m_parser_vars.get() || !expr_var_sp->m_parser_vars->m_lldb_var)
             return Value();
         
-        return *GetVariableValue(exe_ctx, expr_var_sp->m_parser_vars->m_lldb_var, NULL);
+        std::auto_ptr<Value> value(GetVariableValue(exe_ctx, expr_var_sp->m_parser_vars->m_lldb_var, NULL));
+        
+        if (value.get())
+            return *value;
+        else
+            return Value();
     }
     else if (persistent_var_sp)
     {
@@ -969,7 +974,7 @@
             m_parser_vars->m_exe_ctx->GetProcessSP() &&
             m_parser_vars->m_exe_ctx->GetProcessSP()->IsAlive())
         {
-                return persistent_var_sp->m_live_sp->GetValue();
+            return persistent_var_sp->m_live_sp->GetValue();
         }
         else
         {
@@ -986,6 +991,39 @@
     }
 }
 
+Value
+ClangExpressionDeclMap::GetSpecialValue (const ConstString &name)
+{
+    assert(m_parser_vars.get());
+    
+    if (!m_parser_vars->m_exe_ctx)
+        return Value();
+
+    StackFrame *frame = m_parser_vars->m_exe_ctx->GetFramePtr();
+    
+    if (!frame)
+        return Value();
+    
+    VariableList *vars = frame->GetVariableList(false);
+    
+    if (!vars)
+        return Value();
+    
+    lldb::VariableSP var = vars->FindVariable(name);
+    
+    if (!var ||
+        !var->IsInScope(frame) || 
+        !var->LocationIsValidForFrame (frame))
+        return Value();
+    
+    std::auto_ptr<Value> value(GetVariableValue(*m_parser_vars->m_exe_ctx, var, NULL));
+    
+    if (value.get())
+        return *value;
+    else
+        return Value();
+}
+
 // Interface for CommandObjectExpression
 
 bool 
@@ -1535,8 +1573,8 @@
             Error allocate_error;
             
             mem = process->AllocateMemory(pvar_byte_size, 
-                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable, 
-                                                  allocate_error);
+                                          lldb::ePermissionsReadable | lldb::ePermissionsWritable, 
+                                          allocate_error);
             
             if (mem == LLDB_INVALID_ADDRESS)
             {
@@ -1577,9 +1615,9 @@
             // Now write the location of the area into the struct.
             Error write_error;
             if (!process->WriteScalarToMemory (addr, 
-                                                       var_sp->m_live_sp->GetValue().GetScalar(), 
-                                                       process->GetAddressByteSize(), 
-                                                       write_error))
+                                               var_sp->m_live_sp->GetValue().GetScalar(), 
+                                               process->GetAddressByteSize(), 
+                                               write_error))
             {
                 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", var_sp->GetName().GetCString(), write_error.AsCString());
                 return false;

Modified: lldb/trunk/source/Expression/IRInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRInterpreter.cpp?rev=143065&r1=143064&r2=143065&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRInterpreter.cpp (original)
+++ lldb/trunk/source/Expression/IRInterpreter.cpp Wed Oct 26 16:20:00 2011
@@ -576,6 +576,12 @@
         
         const GlobalValue *global_value = dyn_cast<GlobalValue>(value);
         
+        // If the variable is indirected through the argument
+        // array then we need to build an extra level of indirection
+        // for it.  This is the default; only magic arguments like
+        // "this", "self", and "_cmd" are direct.
+        bool indirect_variable = true; 
+        
         // Attempt to resolve the value using the program's data.
         // If it is, the values to be created are:
         //
@@ -586,17 +592,40 @@
         //   resides.  This is an IR-level variable.
         do
         {
-            if (!global_value)
-                break;
-            
             lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+            lldb_private::Value resolved_value;
             
-            clang::NamedDecl *decl = IRForTarget::DeclForGlobal(global_value, &module);
-            
-            if (!decl)
-                break;
-            
-            lldb_private::Value resolved_value = m_decl_map.LookupDecl(decl);
+            if (global_value)
+            {            
+                clang::NamedDecl *decl = IRForTarget::DeclForGlobal(global_value, &module);
+
+                if (!decl)
+                    break;
+                
+                if (isa<clang::FunctionDecl>(decl))
+                {
+                    if (log)
+                        log->Printf("The interpreter does not handle function pointers at the moment");
+                    
+                    return Memory::Region();
+                }
+                
+                resolved_value = m_decl_map.LookupDecl(decl);
+            }
+            else
+            {
+                // Special-case "this", "self", and "_cmd"
+                
+                std::string name_str = value->getNameStr();
+                
+                if (name_str == "this" ||
+                    name_str == "self" ||
+                    name_str == "_cmd")
+                    resolved_value = m_decl_map.GetSpecialValue(lldb_private::ConstString(name_str.c_str()));
+                
+                indirect_variable = false;
+            }
             
             if (resolved_value.GetScalar().GetType() != lldb_private::Scalar::e_void)
             {
@@ -605,7 +634,10 @@
                     Memory::Region data_region = m_memory.Malloc(value->getType());
                     data_region.m_allocation->m_origin = resolved_value;
                     Memory::Region ref_region = m_memory.Malloc(value->getType());
-                    Memory::Region pointer_region = m_memory.Malloc(value->getType());
+                    Memory::Region pointer_region;
+                    
+                    if (indirect_variable)
+                        pointer_region = m_memory.Malloc(value->getType());
                     
                     if (!Cache(data_region.m_allocation, value->getType()))
                         return Memory::Region();
@@ -613,7 +645,7 @@
                     if (ref_region.IsInvalid())
                         return Memory::Region();
                     
-                    if (pointer_region.IsInvalid())
+                    if (pointer_region.IsInvalid() && indirect_variable)
                         return Memory::Region();
                     
                     DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
@@ -621,31 +653,35 @@
                     if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
                         return Memory::Region();
                     
-                    DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
-                    
-                    if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
-                        return Memory::Region();
-                    
-                    m_values[value] = pointer_region;
-                    return pointer_region;
-                }
-                else if (isa<clang::FunctionDecl>(decl))
-                {
-                    if (log)
-                        log->Printf("The interpreter does not handle function pointers at the moment");
-                    
-                    return Memory::Region();
+                    if (indirect_variable)
+                    {
+                        DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
+                        
+                        if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
+                            return Memory::Region();
+                        
+                        m_values[value] = pointer_region;
+                        return pointer_region;
+                    }
+                    else
+                    {
+                        m_values[value] = ref_region;
+                        return ref_region;
+                    }
                 }
                 else
                 {
                     Memory::Region data_region = m_memory.Place(value->getType(), resolved_value.GetScalar().ULongLong(), resolved_value);
                     Memory::Region ref_region = m_memory.Malloc(value->getType());
-                    Memory::Region pointer_region = m_memory.Malloc(value->getType());
+                    Memory::Region pointer_region;
+                    
+                    if (indirect_variable)
+                        pointer_region = m_memory.Malloc(value->getType());
                            
                     if (ref_region.IsInvalid())
                         return Memory::Region();
                     
-                    if (pointer_region.IsInvalid())
+                    if (pointer_region.IsInvalid() && indirect_variable)
                         return Memory::Region();
                     
                     DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
@@ -653,23 +689,30 @@
                     if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
                         return Memory::Region();
                     
-                    DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
-                    
-                    if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
-                        return Memory::Region();
+                    if (indirect_variable)
+                    {
+                        DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
                     
-                    m_values[value] = pointer_region;
+                        if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
+                            return Memory::Region();
+                        
+                        m_values[value] = pointer_region;
+                    }
                     
                     if (log)
                     {
-                        log->Printf("Made an allocation for %s", PrintValue(global_value).c_str());
+                        log->Printf("Made an allocation for %s", PrintValue(value).c_str());
                         log->Printf("  Data contents  : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
                         log->Printf("  Data region    : %llx", (unsigned long long)data_region.m_base);
                         log->Printf("  Ref region     : %llx", (unsigned long long)ref_region.m_base);
-                        log->Printf("  Pointer region : %llx", (unsigned long long)pointer_region.m_base);
+                        if (indirect_variable)
+                            log->Printf("  Pointer region : %llx", (unsigned long long)pointer_region.m_base);
                     }
                     
-                    return pointer_region;
+                    if (indirect_variable)
+                        return pointer_region;
+                    else 
+                        return ref_region;
                 }
             }
         }





More information about the lldb-commits mailing list