[Lldb-commits] [lldb] r143137 - in /lldb/trunk: include/lldb/Expression/ClangExpressionVariable.h include/lldb/Symbol/ClangASTContext.h source/Expression/ClangExpressionDeclMap.cpp source/Symbol/ClangASTContext.cpp

Sean Callanan scallanan at apple.com
Thu Oct 27 12:41:13 PDT 2011


Author: spyffe
Date: Thu Oct 27 14:41:13 2011
New Revision: 143137

URL: http://llvm.org/viewvc/llvm-project?rev=143137&view=rev
Log:
Changed the way the expression parser handles variables
of reference types.  Previously, such variables were
materialized as references to those references, which
caused undesried behavior in Clang and was useless anyway
(the benefit of using references to variables is that it
allows expressions to modify variables in place, but for
references that's not required).

Now we just materialize the references directly, which
fixes a variety of expressions that use references.

Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=143137&r1=143136&r2=143137&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Thu Oct 27 14:41:13 2011
@@ -224,7 +224,8 @@
         EVIsFreezeDried         = 1 << 3,   ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results)
         EVNeedsFreezeDry        = 1 << 4,   ///< Copy from m_live_sp to m_frozen_sp during dematerialization
         EVKeepInTarget          = 1 << 5,   ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it
-        EVUnknownType           = 1 << 6    ///< This is a symbol of unknown type, and the type must be resolved after parsing is complete
+        EVTypeIsReference       = 1 << 6,   ///< The original type of this variable is a reference, so materialize the value rather than the location
+        EVUnknownType           = 1 << 7    ///< This is a symbol of unknown type, and the type must be resolved after parsing is complete
     };
     
     uint16_t m_flags; // takes elements of Flags

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=143137&r1=143136&r2=143137&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Thu Oct 27 14:41:13 2011
@@ -710,6 +710,9 @@
     IsPointerType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL);
 
     static bool
+    IsReferenceType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL);
+    
+    static bool
     IsPointerOrReferenceType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL);
     
     static bool

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=143137&r1=143136&r2=143137&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Thu Oct 27 14:41:13 2011
@@ -1663,6 +1663,8 @@
     VariableSP &var(expr_var->m_parser_vars->m_lldb_var);
     lldb_private::Symbol *sym(expr_var->m_parser_vars->m_lldb_sym);
     
+    bool is_reference(expr_var->m_flags & ClangExpressionVariable::EVTypeIsReference);
+    
     std::auto_ptr<lldb_private::Value> location_value;
 
     if (var)
@@ -1741,15 +1743,42 @@
             {
                 Error write_error;
 
-                if (!process->WriteScalarToMemory (addr, 
-                                                           location_value->GetScalar(), 
-                                                           process->GetAddressByteSize(), 
-                                                           write_error))
+                if (is_reference)
                 {
-                    err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 
-                                                  name.GetCString(), 
-                                                  write_error.AsCString());
-                    return false;
+                    Error read_error;
+                    
+                    addr_t ref_value = process->ReadPointerFromMemory(location_value->GetScalar().ULongLong(), read_error);
+                    
+                    if (!read_error.Success())
+                    {
+                        err.SetErrorStringWithFormat ("Couldn't read reference to %s from the target: %s",
+                                                      name.GetCString(),
+                                                      read_error.AsCString());
+                        return false;
+                    }
+                    
+                    if (!process->WritePointerToMemory(addr,
+                                                       ref_value,
+                                                       write_error))
+                    {
+                        err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 
+                                                      name.GetCString(), 
+                                                      write_error.AsCString());
+                        return false;
+                    }
+                }
+                else
+                {
+                    if (!process->WriteScalarToMemory (addr, 
+                                                       location_value->GetScalar(), 
+                                                       process->GetAddressByteSize(), 
+                                                       write_error))
+                    {
+                        err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 
+                                                      name.GetCString(), 
+                                                      write_error.AsCString());
+                        return false;
+                    }
                 }
             }
         }
@@ -1792,6 +1821,9 @@
             
             if (dematerialize)
             {
+                if (is_reference)
+                    return true; // reference types don't need demateralizing
+                
                 // Get the location of the spare memory area out of the variable's live data.
                 
                 if (!expr_var->m_live_sp)
@@ -1839,14 +1871,45 @@
             }
             else
             {
+                Error write_error;
+                
+                RegisterValue reg_value;
+                
+                if (!reg_ctx->ReadRegister (reg_info, reg_value))
+                {
+                    err.SetErrorStringWithFormat ("Couldn't read %s from %s", 
+                                                  name.GetCString(), 
+                                                  reg_info->name);
+                    return false;
+                }
+
+                if (is_reference)
+                {
+                    write_error = reg_ctx->WriteRegisterValueToMemory(reg_info, 
+                                                                      addr,
+                                                                      process->GetAddressByteSize(), 
+                                                                      reg_value);
+                    
+                    if (!write_error.Success())
+                    {
+                        err.SetErrorStringWithFormat ("Couldn't write %s from register %s to the target: %s", 
+                                                      name.GetCString(),
+                                                      reg_info->name,
+                                                      write_error.AsCString());
+                        return false;
+                    }
+                    
+                    return true;
+                }
+
                 // Allocate a spare memory area to place the register's contents into.  This memory area will be pointed to by the slot in the
                 // struct.
                 
                 Error allocate_error;
                 
                 Scalar reg_addr (process->AllocateMemory (value_byte_size, 
-                                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable, 
-                                                                  allocate_error));
+                                                          lldb::ePermissionsReadable | lldb::ePermissionsWritable, 
+                                                          allocate_error));
                 
                 if (reg_addr.ULongLong() == LLDB_INVALID_ADDRESS)
                 {
@@ -1867,13 +1930,11 @@
                                                                       value_byte_size);
                 
                 // Now write the location of the area into the struct.
-                
-                Error write_error;
-                
+                                
                 if (!process->WriteScalarToMemory (addr, 
-                                                           reg_addr, 
-                                                           process->GetAddressByteSize(), 
-                                                           write_error))
+                                                   reg_addr, 
+                                                   process->GetAddressByteSize(), 
+                                                   write_error))
                 {
                     err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 
                                                   name.GetCString(), 
@@ -1889,8 +1950,6 @@
                     return false;
                 }
 
-                RegisterValue reg_value;
-
                 if (!reg_ctx->ReadRegister (reg_info, reg_value))
                 {
                     err.SetErrorStringWithFormat ("Couldn't read %s from %s", 
@@ -2924,7 +2983,15 @@
     if (!var_location)
         return;
     
-    NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(pt.GetASTContext(), pt.GetOpaqueQualType()));
+    NamedDecl *var_decl;
+    
+    bool is_reference = ClangASTContext::IsReferenceType(pt.GetOpaqueQualType());
+
+    if (is_reference)
+        var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
+    else
+        var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(pt.GetASTContext(), pt.GetOpaqueQualType()));
+        
     std::string decl_name(context.m_decl_name.getAsString());
     ConstString entity_name(decl_name.c_str());
     ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->GetBestExecutionContextScope (),
@@ -2940,6 +3007,9 @@
     entity->m_parser_vars->m_lldb_value  = var_location;
     entity->m_parser_vars->m_lldb_var    = var;
     
+    if (is_reference)
+        entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
+    
     if (log)
     {
         ASTDumper ast_dumper(var_decl);        

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=143137&r1=143136&r2=143137&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Oct 27 14:41:13 2011
@@ -4964,6 +4964,35 @@
     return false;
 }
 
+bool
+ClangASTContext::IsReferenceType (clang_type_t clang_type, clang_type_t *target_type)
+{
+    if (clang_type == NULL)
+        return false;
+    
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+    switch (type_class)
+    {
+    case clang::Type::LValueReference:
+        if (target_type)
+            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
+        return true;
+    case clang::Type::RValueReference:
+        if (target_type)
+            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
+        return true;
+    case clang::Type::Typedef:
+        return ClangASTContext::IsReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+    case clang::Type::Elaborated:
+        return ClangASTContext::IsReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+    default:
+        break;
+    }
+    
+    return false;
+}
 
 bool
 ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)





More information about the lldb-commits mailing list