[Lldb-commits] [lldb] r160211 - in /lldb/trunk: include/lldb/Symbol/ include/lldb/Target/ source/API/ source/Commands/ source/Core/ source/Expression/ source/Symbol/ source/Target/

Greg Clayton gclayton at apple.com
Fri Jul 13 17:53:56 PDT 2012


Author: gclayton
Date: Fri Jul 13 19:53:55 2012
New Revision: 160211

URL: http://llvm.org/viewvc/llvm-project?rev=160211&view=rev
Log:
<rdar://problem/11870357>

Allow "frame variable" to find ivars without the need for "this->" or "self->".  

Modified:
    lldb/trunk/include/lldb/Symbol/Block.h
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Symbol/SymbolContext.h
    lldb/trunk/include/lldb/Symbol/VariableList.h
    lldb/trunk/include/lldb/Target/StackFrame.h
    lldb/trunk/source/API/SBFrame.cpp
    lldb/trunk/source/Commands/CommandObjectFrame.cpp
    lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Symbol/Block.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Symbol/SymbolContext.cpp
    lldb/trunk/source/Symbol/VariableList.cpp
    lldb/trunk/source/Target/StackFrame.cpp

Modified: lldb/trunk/include/lldb/Symbol/Block.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Block.h?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Block.h (original)
+++ lldb/trunk/include/lldb/Symbol/Block.h Fri Jul 13 19:53:55 2012
@@ -263,6 +263,22 @@
     }
 
     //------------------------------------------------------------------
+    /// Get the variable list for this block only.
+    ///
+    /// @param[in] can_create
+    ///     If \b true, the variables can be parsed if they already
+    ///     haven't been, else the current state of the block will be
+    ///     returned. 
+    ///
+    /// @return
+    ///     A variable list shared pointer that contains all variables
+    ///     for this block.
+    //------------------------------------------------------------------
+    lldb::VariableListSP
+    GetBlockVariableList (bool can_create);
+
+
+    //------------------------------------------------------------------
     /// Get the variable list for this block and optionally all child
     /// blocks if \a get_child_variables is \b true.
     ///
@@ -278,7 +294,7 @@
     ///     point.
     ///
     /// @param[in] add_inline_child_block_variables
-    ///     If this is \b false, no child variables of child blocks 
+    ///     If this is \b false, no child variables of child blocks
     ///     that are inlined functions will be gotten. If \b true then
     ///     all child variables will be added regardless of whether they
     ///     come from inlined functions or not.
@@ -287,10 +303,6 @@
     ///     A variable list shared pointer that contains all variables
     ///     for this block.
     //------------------------------------------------------------------
-    lldb::VariableListSP
-    GetBlockVariableList (bool can_create);
-
-
     uint32_t
     AppendBlockVariables (bool can_create,
                           bool get_child_block_variables,
@@ -345,7 +357,7 @@
     }
     
     clang::DeclContext *
-    GetClangDeclContextForInlinedFunction();
+    GetClangDeclContext();
 
     //------------------------------------------------------------------
     /// Get the memory cost of this object.

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Fri Jul 13 19:53:55 2012
@@ -237,6 +237,12 @@
         return GetTranslationUnitDecl (getASTContext());
     }
     
+    static bool
+    GetClassMethodInfoForDeclContext (clang::DeclContext *decl_ctx,
+                                      lldb::LanguageType &language,
+                                      bool &is_instance_method,
+                                      ConstString &language_object_name);
+    
     static lldb::clang_type_t
     CopyType(clang::ASTContext *dest_context, 
              clang::ASTContext *source_context,

Modified: lldb/trunk/include/lldb/Symbol/SymbolContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolContext.h?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/SymbolContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/SymbolContext.h Fri Jul 13 19:53:55 2012
@@ -220,6 +220,56 @@
     uint32_t
     GetResolvedMask () const;
 
+    
+    //------------------------------------------------------------------
+    /// Find a block that defines the function represented by this
+    /// symbol context.
+    ///
+    /// If this symbol context points to a block that is an inlined
+    /// function, or is contained within an inlined function, the block
+    /// that defines the inlined function is returned.
+    ///
+    /// If this symbol context has no block in it, or the block is not
+    /// itself an inlined function block or contained within one, we
+    /// return the top level function block.
+    ///
+    /// This is a handy function to call when you want to get the block
+    /// whose variable list will include the arguments for the function
+    /// that is represented by this symbol context (whether the function
+    /// is an inline function or not).
+    ///
+    /// @return
+    ///     The block object pointer that defines the function that is
+    ///     represented by this symbol context object, NULL otherwise.
+    //------------------------------------------------------------------
+    Block *
+    GetFunctionBlock ();
+
+    
+    //------------------------------------------------------------------
+    /// If this symbol context represents a function that is a method,
+    /// return true and provide information about the method.
+    ///
+    /// @param[out] language
+    ///     If \b true is returned, the language for the method.
+    ///
+    /// @param[out] is_instance_method
+    ///     If \b true is returned, \b true if this is a instance method,
+    ///     \b false if this is a static/class function.
+    ///
+    /// @param[out] language_object_name
+    ///     If \b true is returned, the name of the artificial variable
+    ///     for the language ("this" for C++, "self" for ObjC).
+    ///
+    /// @return
+    ///     \b True if this symbol context represents a function that
+    ///     is a method of a class, \b false otherwise.
+    //------------------------------------------------------------------
+    bool
+    GetFunctionMethodInfo (lldb::LanguageType &language,
+                           bool &is_instance_method,
+                           ConstString &language_object_name);
+
     //------------------------------------------------------------------
     /// Find a name of the innermost function for the symbol context.
     ///

Modified: lldb/trunk/include/lldb/Symbol/VariableList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/VariableList.h?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/VariableList.h (original)
+++ lldb/trunk/include/lldb/Symbol/VariableList.h Fri Jul 13 19:53:55 2012
@@ -50,6 +50,11 @@
     lldb::VariableSP
     FindVariable (const ConstString& name);
 
+    // Find the argument variable that represents the language specific
+    // object pointer ("this" in C++, or "self" in Objective C).
+    lldb::VariableSP
+    FindArtificialObjectVariable (lldb::LanguageType language) const;
+
     uint32_t
     FindVariableIndex (const lldb::VariableSP &var_sp);
 

Modified: lldb/trunk/include/lldb/Target/StackFrame.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StackFrame.h (original)
+++ lldb/trunk/include/lldb/Target/StackFrame.h Fri Jul 13 19:53:55 2012
@@ -36,7 +36,8 @@
         eExpressionPathOptionCheckPtrVsMember       = (1u << 0),
         eExpressionPathOptionsNoFragileObjcIvar     = (1u << 1),
         eExpressionPathOptionsNoSyntheticChildren   = (1u << 2),
-        eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3)
+        eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3),
+        eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4)
     };
     //------------------------------------------------------------------
     // Constructors and Destructors

Modified: lldb/trunk/source/API/SBFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/API/SBFrame.cpp (original)
+++ lldb/trunk/source/API/SBFrame.cpp Fri Jul 13 19:53:55 2012
@@ -534,7 +534,7 @@
             Error error;
             ValueObjectSP value_sp (frame->GetValueForVariableExpressionPath (var_path, 
                                                                               use_dynamic,
-                                                                              StackFrame::eExpressionPathOptionCheckPtrVsMember,
+                                                                              StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
                                                                               var_sp,
                                                                               error));
             sb_value.SetSP(value_sp);

Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Fri Jul 13 19:53:55 2012
@@ -483,7 +483,8 @@
                     else // No regex, either exact variable names or variable expressions.
                     {
                         Error error;
-                        uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember;
+                        uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
+                                                     StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
                         lldb::VariableSP var_sp;
                         valobj_sp = frame->GetValueForVariableExpressionPath (name_cstr, 
                                                                               m_varobj_options.use_dynamic, 

Modified: lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp Fri Jul 13 19:53:55 2012
@@ -1015,7 +1015,8 @@
 
         // Things have checked out ok...
         Error error;
-        uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember;
+        uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
+                                     StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
         valobj_sp = frame->GetValueForVariableExpressionPath (command.GetArgumentAtIndex(0), 
                                                               eNoDynamicValues, 
                                                               expr_path_options,

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Fri Jul 13 19:53:55 2012
@@ -987,48 +987,6 @@
     return true;
 }
 
-
-static ValueObjectSP
-ExpandExpressionPath (ValueObject* valobj,
-                      StackFrame* frame,
-                      bool* do_deref_pointer,
-                      const char* var_name_begin,
-                      const char* var_name_final,
-                      Error& error)
-{
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
-    StreamString sstring;
-    VariableSP var_sp;
-    
-    if (*do_deref_pointer)
-    {
-        if (log)
-            log->Printf("been told to deref_pointer by caller");
-        sstring.PutChar('*');
-    }
-    else if (valobj->IsDereferenceOfParent() && ClangASTContext::IsPointerType(valobj->GetParent()->GetClangType()) && !valobj->IsArrayItemForPointer())
-    {
-        if (log)
-            log->Printf("decided to deref_pointer myself");
-        sstring.PutChar('*');
-        *do_deref_pointer = true;
-    }
-
-    valobj->GetExpressionPath(sstring, true, ValueObject::eGetExpressionPathFormatHonorPointers);
-    if (log)
-        log->Printf("expression path to expand in phase 0: %s",sstring.GetData());
-    sstring.PutRawBytes(var_name_begin+3, var_name_final-var_name_begin-3);
-    if (log)
-        log->Printf("expression path to expand in phase 1: %s",sstring.GetData());
-    std::string name = std::string(sstring.GetData());
-    ValueObjectSP target = frame->GetValueForVariableExpressionPath (name.c_str(),
-                                                                     eNoDynamicValues, 
-                                                                     0,
-                                                                     var_sp,
-                                                                     error);
-    return target;
-}
-
 static ValueObjectSP
 ExpandIndexedExpression (ValueObject* valobj,
                          uint32_t index,

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri Jul 13 19:53:55 2012
@@ -2443,12 +2443,13 @@
             if (!sym_ctx.function)
                 return;
             
-            clang::DeclContext *decl_context;
-            
-            if (sym_ctx.block && sym_ctx.block->GetInlinedFunctionInfo())
-                decl_context = sym_ctx.block->GetClangDeclContextForInlinedFunction();
-            else
-                decl_context = sym_ctx.function->GetClangDeclContext();
+            // Get the block that defines the function
+            Block *function_block = sym_ctx.GetFunctionBlock();
+
+            if (!function_block)
+                return;
+
+            clang::DeclContext *decl_context = function_block->GetClangDeclContext();
             
             if (!decl_context)
                 return;
@@ -2501,12 +2502,13 @@
             if (!sym_ctx.function)
                 return;
             
-            clang::DeclContext *decl_context;
+            // Get the block that defines the function
+            Block *function_block = sym_ctx.GetFunctionBlock();
             
-            if (sym_ctx.block && sym_ctx.block->GetInlinedFunctionInfo())
-                decl_context = sym_ctx.block->GetClangDeclContextForInlinedFunction();
-            else
-                decl_context = sym_ctx.function->GetClangDeclContext();
+            if (!function_block)
+                return;
+            
+            clang::DeclContext *decl_context = function_block->GetClangDeclContext();
             
             if (!decl_context)
                 return;

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Fri Jul 13 19:53:55 2012
@@ -115,13 +115,14 @@
     if (!sym_ctx.function)
         return;
     
-    clang::DeclContext *decl_context;
+    // Find the block that defines the function represented by "sym_ctx"
+    Block *function_block = sym_ctx.GetFunctionBlock();
     
-    if (sym_ctx.block && sym_ctx.block->GetInlinedFunctionInfo())
-        decl_context = sym_ctx.block->GetClangDeclContextForInlinedFunction();
-    else
-        decl_context = sym_ctx.function->GetClangDeclContext();
-        
+    if (!function_block)
+        return;
+
+    clang::DeclContext *decl_context = function_block->GetClangDeclContext();
+
     if (!decl_context)
         return;
             
@@ -131,24 +132,22 @@
         {
             if (m_enforce_valid_object)
             {
-                VariableList *vars = frame->GetVariableList(false);
+                lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
                 
                 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
                 
-                if (!vars)
+                if (!variable_list_sp)
                 {
-                    err.SetErrorToGenericError();
                     err.SetErrorString(thisErrorString);
                     return;
                 }
                 
-                lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
+                lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
                 
-                if (!this_var ||
-                    !this_var->IsInScope(frame) || 
-                    !this_var->LocationIsValidForFrame (frame))
+                if (!this_var_sp ||
+                    !this_var_sp->IsInScope(frame) || 
+                    !this_var_sp->LocationIsValidForFrame (frame))
                 {
-                    err.SetErrorToGenericError();
                     err.SetErrorString(thisErrorString);
                     return;
                 }
@@ -164,24 +163,22 @@
         {
             if (m_enforce_valid_object)
             {
-                VariableList *vars = frame->GetVariableList(false);
+                lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
                 
                 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
                 
-                if (!vars)
+                if (!variable_list_sp)
                 {
-                    err.SetErrorToGenericError();
                     err.SetErrorString(selfErrorString);
                     return;
                 }
                 
-                lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
+                lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
                 
-                if (!self_var || 
-                    !self_var->IsInScope(frame) || 
-                    !self_var->LocationIsValidForFrame (frame))
+                if (!self_variable_sp || 
+                    !self_variable_sp->IsInScope(frame) || 
+                    !self_variable_sp->LocationIsValidForFrame (frame))
                 {
-                    err.SetErrorToGenericError();
                     err.SetErrorString(selfErrorString);
                     return;
                 }

Modified: lldb/trunk/source/Symbol/Block.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Block.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Block.cpp (original)
+++ lldb/trunk/source/Symbol/Block.cpp Fri Jul 13 19:53:55 2012
@@ -542,7 +542,7 @@
 }
 
 clang::DeclContext *
-Block::GetClangDeclContextForInlinedFunction()
+Block::GetClangDeclContext()
 {
     SymbolContext sc;
     

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Jul 13 19:53:55 2012
@@ -6330,3 +6330,49 @@
     return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
 }
 
+
+bool
+ClangASTContext::GetClassMethodInfoForDeclContext (clang::DeclContext *decl_ctx,
+                                                   lldb::LanguageType &language,
+                                                   bool &is_instance_method,
+                                                   ConstString &language_object_name)
+{
+    language_object_name.Clear();
+    language = eLanguageTypeUnknown;
+    is_instance_method = false;
+
+    if (decl_ctx)
+    {
+        if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_ctx))
+        {
+            if (method_decl->isStatic())
+            {
+                is_instance_method = false;
+            }
+            else
+            {
+                language_object_name.SetCString("this");
+                is_instance_method = true;
+            }
+            language = eLanguageTypeC_plus_plus;
+            return true;
+        }
+        else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_ctx))
+        {
+            // Both static and instance methods have a "self" object in objective C
+            language_object_name.SetCString("self");
+            if (method_decl->isInstanceMethod())
+            {
+                is_instance_method = true;
+            }
+            else
+            {
+                is_instance_method = false;
+            }
+            language = eLanguageTypeObjC;
+            return true;
+        }
+    }
+    return false;
+}
+

Modified: lldb/trunk/source/Symbol/SymbolContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/SymbolContext.cpp (original)
+++ lldb/trunk/source/Symbol/SymbolContext.cpp Fri Jul 13 19:53:55 2012
@@ -13,6 +13,8 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Interpreter/Args.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/Symbol.h"
@@ -535,7 +537,61 @@
     return false;
 }
 
-ConstString 
+Block *
+SymbolContext::GetFunctionBlock ()
+{
+    if (function)
+    {
+        if (block)
+        {
+            // If this symbol context has a block, check to see if this block
+            // is itself, or is contained within a block with inlined function
+            // information. If so, then the inlined block is the block that
+            // defines the function.
+            Block *inlined_block = block->GetContainingInlinedBlock();
+            if (inlined_block)
+                return inlined_block;
+
+            // The block in this symbol context is not inside an inlined
+            // block, so the block that defines the function is the function's
+            // top level block, which is returned below.
+        }
+
+        // There is no block information in this symbol context, so we must
+        // assume that the block that is desired is the top level block of
+        // the function itself.
+        return &function->GetBlock(true);
+    }
+    return NULL;
+}
+
+bool
+SymbolContext::GetFunctionMethodInfo (lldb::LanguageType &language,
+                                      bool &is_instance_method,
+                                      ConstString &language_object_name)
+
+
+{
+    Block *function_block = GetFunctionBlock ();
+    if (function_block)
+    {
+        clang::DeclContext *decl_context = function_block->GetClangDeclContext();
+        
+        if (decl_context)
+        {
+            return ClangASTContext::GetClassMethodInfoForDeclContext (decl_context,
+                                                                      language,
+                                                                      is_instance_method,
+                                                                      language_object_name);
+        }
+    }
+    language = eLanguageTypeUnknown;
+    is_instance_method = false;
+    language_object_name.Clear();
+    return false;
+}
+
+ConstString
 SymbolContext::GetFunctionName (Mangled::NamePreference preference)
 {
     if (function)

Modified: lldb/trunk/source/Symbol/VariableList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/VariableList.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/VariableList.cpp (original)
+++ lldb/trunk/source/Symbol/VariableList.cpp Fri Jul 13 19:53:55 2012
@@ -176,3 +176,40 @@
     }
 }
 
+lldb::VariableSP
+VariableList::FindArtificialObjectVariable (lldb::LanguageType language) const
+{
+    lldb::VariableSP object_variable_sp;
+    ConstString object_variable_name;
+    switch (language)
+    {
+        case eLanguageTypeC_plus_plus:
+            object_variable_name.SetCString("this");
+            break;
+
+        case eLanguageTypeObjC:
+        case eLanguageTypeObjC_plus_plus:
+            object_variable_name.SetCString("self");
+            break;
+
+        default:
+            break;
+    }
+    if (object_variable_name)
+    {
+        const_iterator pos, end = m_variables.end();
+        for (pos = m_variables.begin(); pos != end; ++pos)
+        {
+            Variable *variable = pos->get();
+            if (variable->IsArtificial() &&
+                variable->GetScope() == eValueTypeVariableArgument &&
+                variable->GetName() == object_variable_name)
+            {
+                object_variable_sp = *pos;
+                break;
+            }
+        }
+    }
+    return object_variable_sp;
+}
+

Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=160211&r1=160210&r2=160211&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Fri Jul 13 19:53:55 2012
@@ -513,7 +513,7 @@
 
 
 ValueObjectSP
-StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, 
+StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
                                                DynamicValueType use_dynamic,
                                                uint32_t options, 
                                                VariableSP &var_sp,
@@ -562,13 +562,42 @@
                 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
 
             var_sp = variable_list->FindVariable(name_const_string);
+            
+            bool synthetically_added_instance_object = false;
+
+            if (var_sp)
+            {
+                var_path.erase (0, name_const_string.GetLength ());
+            }
+            else if (options & eExpressionPathOptionsAllowDirectIVarAccess)
+            {
+                // Check for direct ivars access which helps us with implicit
+                // access to ivars with the "this->" or "self->"
+                GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock);
+                lldb::LanguageType method_language = eLanguageTypeUnknown;
+                bool is_instance_method = false;
+                ConstString method_object_name;
+                if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name))
+                {
+                    if (is_instance_method && method_object_name)
+                    {
+                        var_sp = variable_list->FindVariable(method_object_name);
+                        if (var_sp)
+                        {
+                            separator_idx = 0;
+                            var_path.insert(0, "->");
+                            synthetically_added_instance_object = true;
+                        }
+                    }
+                }
+            }
+
             if (var_sp)
             {
                 valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic);
                 if (!valobj_sp)
                     return valobj_sp;
                     
-                var_path.erase (0, name_const_string.GetLength ());
                 // We are dumping at least one child
                 while (separator_idx != std::string::npos)
                 {
@@ -651,23 +680,35 @@
                                 if (no_synth_child || !child_valobj_sp)
                                 {
                                     // No child member with name "child_name"
-                                    valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                    if (child_name)
+                                    if (synthetically_added_instance_object)
                                     {
-                                        error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"", 
-                                                                        child_name.GetCString(), 
-                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                        var_expr_path_strm.GetString().c_str());
+                                        // We added a "this->" or "self->" to the beginning of the expression
+                                        // and this is the first pointer ivar access, so just return the normal
+                                        // error
+                                        error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame",
+                                                                       name_const_string.GetCString());
                                     }
                                     else
                                     {
-                                        error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
-                                                                        var_expr_path_strm.GetString().c_str(),
-                                                                        var_expr_cstr);
+                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
+                                        if (child_name)
+                                        {
+                                            error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"", 
+                                                                            child_name.GetCString(), 
+                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                                                                            var_expr_path_strm.GetString().c_str());
+                                        }
+                                        else
+                                        {
+                                            error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
+                                                                            var_expr_path_strm.GetString().c_str(),
+                                                                            var_expr_cstr);
+                                        }
                                     }
                                     return ValueObjectSP();
                                 }
                             }
+                            synthetically_added_instance_object = false;
                             // Remove the child name from the path
                             var_path.erase(0, child_name.GetLength());
                             if (use_dynamic != eNoDynamicValues)





More information about the lldb-commits mailing list