diff options
-rw-r--r-- | lldb/include/lldb/API/SBFrame.h | 3 | ||||
-rw-r--r-- | lldb/include/lldb/Core/DataExtractor.h | 4 | ||||
-rw-r--r-- | lldb/include/lldb/Core/ValueObject.h | 13 | ||||
-rw-r--r-- | lldb/include/lldb/Core/ValueObjectConstResult.h | 71 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionVariable.h | 71 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-enumerations.h | 3 | ||||
-rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 8 | ||||
-rw-r--r-- | lldb/source/API/SBFrame.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.cpp | 60 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectFrame.cpp | 183 | ||||
-rw-r--r-- | lldb/source/Core/DataExtractor.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Core/ValueObject.cpp | 124 | ||||
-rw-r--r-- | lldb/source/Core/ValueObjectConstResult.cpp | 109 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionVariable.cpp | 193 | ||||
-rw-r--r-- | lldb/source/Expression/ClangPersistentVariables.cpp | 13 |
16 files changed, 518 insertions, 355 deletions
diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h index aa2fad87cce..f0430fe022c 100644 --- a/lldb/include/lldb/API/SBFrame.h +++ b/lldb/include/lldb/API/SBFrame.h @@ -64,6 +64,9 @@ public: lldb::SBBlock GetBlock () const; + lldb::SBValue + EvaluateExpression (const char *expr); + // Gets the lexical block that defines the stack frame. Another way to think // of this is it will return the block that contains all of the variables // for a stack frame. Inlined functions are represented as SBBlock objects diff --git a/lldb/include/lldb/Core/DataExtractor.h b/lldb/include/lldb/Core/DataExtractor.h index 9587222245d..ae5849dfdc1 100644 --- a/lldb/include/lldb/Core/DataExtractor.h +++ b/lldb/include/lldb/Core/DataExtractor.h @@ -99,7 +99,7 @@ public: /// @param[in] addr_size /// A new address byte size value. //------------------------------------------------------------------ - DataExtractor (lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint8_t addr_size); + DataExtractor (const lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint8_t addr_size); //------------------------------------------------------------------ /// Construct with a subset of \a data. @@ -1068,7 +1068,7 @@ public: /// The number of bytes that this object now contains. //------------------------------------------------------------------ uint32_t - SetData (lldb::DataBufferSP& data_sp, uint32_t offset = 0, uint32_t length = UINT32_MAX); + SetData (const lldb::DataBufferSP& data_sp, uint32_t offset = 0, uint32_t length = UINT32_MAX); //------------------------------------------------------------------ /// Set the byte_order value. diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index fc61060d75e..592d6ab21a8 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -188,6 +188,19 @@ public: bool SetDynamicValue (); + static void + DumpValueObject (Stream &s, + ExecutionContextScope *exe_scope, + ValueObject *valobj, + const char *root_valobj_name, + uint32_t ptr_depth, + uint32_t curr_depth, + uint32_t max_depth, + bool show_types, + bool show_location, + bool use_objc, + bool scope_already_checked); + protected: //------------------------------------------------------------------ // Classes that inherit from ValueObject can see and modify these diff --git a/lldb/include/lldb/Core/ValueObjectConstResult.h b/lldb/include/lldb/Core/ValueObjectConstResult.h new file mode 100644 index 00000000000..c1e82920f72 --- /dev/null +++ b/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -0,0 +1,71 @@ +//===-- ValueObjectConstResult.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ValueObjectChild_h_ +#define liblldb_ValueObjectChild_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/ValueObject.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// A child of another ValueObject. +//---------------------------------------------------------------------- +class ValueObjectConstResult : public ValueObject +{ +public: + ValueObjectConstResult (clang::ASTContext *clang_ast, + void *clang_type, + const ConstString &name, + const lldb::DataBufferSP &result_data_sp, + lldb::ByteOrder byte_order, + uint8_t addr_size); + + + virtual ~ValueObjectConstResult(); + + virtual size_t + GetByteSize(); + + virtual clang::ASTContext * + GetClangAST (); + + virtual void * + GetClangType (); + + virtual lldb::ValueType + GetValueType() const; + + virtual uint32_t + CalculateNumChildren(); + + virtual ConstString + GetTypeName(); + + virtual void + UpdateValue (ExecutionContextScope *exe_scope); + + virtual bool + IsInScope (StackFrame *frame); + +protected: + clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from + ConstString m_type_name; + +private: + DISALLOW_COPY_AND_ASSIGN (ValueObjectConstResult); +}; + +} // namespace lldb_private + +#endif // liblldb_ValueObjectChild_h_ diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h index 2554fd84ff6..543efb65ae2 100644 --- a/lldb/include/lldb/Expression/ClangExpressionVariable.h +++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h @@ -82,6 +82,9 @@ struct ClangExpressionVariable bool PointValueAtData(Value &value, ExecutionContext *exe_ctx); + lldb::ValueObjectSP + GetExpressionResult (ExecutionContext *exe_ctx); + //---------------------------------------------------------------------- /// The following values should stay valid for the life of the variable //---------------------------------------------------------------------- @@ -98,6 +101,15 @@ struct ClangExpressionVariable /// The following values should not live beyond parsing //---------------------------------------------------------------------- struct ParserVars { + + ParserVars() : + m_parser_type(), + m_named_decl (NULL), + m_llvm_value (NULL), + m_lldb_value (NULL) + { + } + TypeFromParser m_parser_type; ///< The type of the variable according to the parser const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue @@ -127,6 +139,13 @@ struct ClangExpressionVariable /// The following values are valid if the variable is used by JIT code //---------------------------------------------------------------------- struct JITVars { + JITVars () : + m_alignment (0), + m_size (0), + m_offset (0) + { + } + off_t m_alignment; ///< The required alignment of the variable, in bytes size_t m_size; ///< The space required for the variable, in bytes off_t m_offset; ///< The offset of the variable in the struct, in bytes @@ -151,24 +170,15 @@ struct ClangExpressionVariable m_jit_vars.reset(); } - //---------------------------------------------------------------------- - /// The following values are valid if the value contains its own data - //---------------------------------------------------------------------- - struct DataVars { - lldb_private::DataBufferHeap *m_data; ///< The heap area allocated to contain this variable's data. Responsibility for deleting this falls to whoever uses the variable last - }; - std::auto_ptr<DataVars> m_data_vars; + lldb::DataBufferSP m_data_sp; //---------------------------------------------------------------------- /// Make this variable usable for storing its data internally by /// allocating data-specific variables //---------------------------------------------------------------------- - void EnableDataVars() - { - if (!m_jit_vars.get()) - m_data_vars.reset(new struct DataVars); - } - + void + EnableDataVars(); + //---------------------------------------------------------------------- /// Deallocate data-specific variables //---------------------------------------------------------------------- @@ -180,40 +190,7 @@ struct ClangExpressionVariable size_t Size () { return (m_user_type.GetClangTypeBitWidth () + 7) / 8; - } - - //---------------------------------------------------------------------- - /// Pretty-print the variable, assuming it contains its own data - /// - /// @param[in] output_stream - /// The stream to pretty-print on. - /// - /// @param[in] exe_ctx - /// The execution context to use when resolving the contents of the - /// variable. - /// - /// @param[in] format - /// The format to print the variable in - /// - /// @param[in] show_types - /// If true, print the type of the variable - /// - /// @param[in] show_summary - /// If true, print a summary of the variable's type - /// - /// @param[in] verbose - /// If true, be verbose in printing the value of the variable - /// - /// @return - /// An Error describing the result of the operation. If Error::Success() - /// returns true, the pretty printing completed successfully. - //---------------------------------------------------------------------- - Error Print(Stream &output_stream, - ExecutionContext &exe_ctx, - lldb::Format format, - bool show_types, - bool show_summary, - bool verbose); + } }; //---------------------------------------------------------------------- diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index fdd50c86701..2d634e674b6 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -311,7 +311,8 @@ typedef enum ValueType eValueTypeVariableArgument = 3, // function argument variables eValueTypeVariableLocal = 4, // function local variables eValueTypeRegister = 5, // stack frame register value - eValueTypeRegisterSet = 6 // A collection of stack frame register values + eValueTypeRegisterSet = 6, // A collection of stack frame register values + eValueTypeConstResult = 7, // function local variables } ValueType; //---------------------------------------------------------------------- diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 1b2fa64627b..370b6343039 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ 261B5A5411C3F2AD00AABD0A /* SharingPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 261B5A5211C3F2AD00AABD0A /* SharingPtr.cpp */; }; 261B5A5511C3F2AD00AABD0A /* SharingPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 261B5A5311C3F2AD00AABD0A /* SharingPtr.h */; settings = {ATTRIBUTES = (Public, ); }; }; 262CFC7711A4510000946C6C /* debugserver in Resources */ = {isa = PBXBuildFile; fileRef = 26CE05A0115C31E50022F371 /* debugserver */; }; + 26424E3D125986CB0016D82C /* ValueObjectConstResult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26424E3C125986CB0016D82C /* ValueObjectConstResult.cpp */; }; + 26424E3F125986D30016D82C /* ValueObjectConstResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 26424E3E125986D30016D82C /* ValueObjectConstResult.h */; }; 264723A611FA076E00DE380C /* CleanUp.h in Headers */ = {isa = PBXBuildFile; fileRef = 264723A511FA076E00DE380C /* CleanUp.h */; }; 265ABF6310F42EE900531910 /* DebugSymbols.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 265ABF6210F42EE900531910 /* DebugSymbols.framework */; }; 2668020E115FD12C008E1FE4 /* lldb-defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7C2510F1B3BC00F91463 /* lldb-defines.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -559,6 +561,8 @@ 263664921140A4930075843B /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Debugger.cpp; path = source/Core/Debugger.cpp; sourceTree = "<group>"; }; 263664941140A4C10075843B /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Debugger.h; path = include/lldb/Core/Debugger.h; sourceTree = "<group>"; }; 263FEDA5112CC1DA00E4C208 /* ThreadSafeSTLMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSafeSTLMap.h; path = include/lldb/Core/ThreadSafeSTLMap.h; sourceTree = "<group>"; }; + 26424E3C125986CB0016D82C /* ValueObjectConstResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResult.cpp; path = source/Core/ValueObjectConstResult.cpp; sourceTree = "<group>"; }; + 26424E3E125986D30016D82C /* ValueObjectConstResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResult.h; path = include/lldb/Core/ValueObjectConstResult.h; sourceTree = "<group>"; }; 264334381110F63100CDB6C6 /* ValueObjectRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectRegister.cpp; path = source/Core/ValueObjectRegister.cpp; sourceTree = "<group>"; }; 2643343A1110F63C00CDB6C6 /* ValueObjectRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectRegister.h; path = include/lldb/Core/ValueObjectRegister.h; sourceTree = "<group>"; }; 264723A511FA076E00DE380C /* CleanUp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CleanUp.h; path = include/lldb/Utility/CleanUp.h; sourceTree = "<group>"; }; @@ -1745,6 +1749,8 @@ 26BC7E9A10F1B85900F91463 /* ValueObject.cpp */, 26BC7D8310F1B77400F91463 /* ValueObjectChild.h */, 26BC7E9B10F1B85900F91463 /* ValueObjectChild.cpp */, + 26424E3E125986D30016D82C /* ValueObjectConstResult.h */, + 26424E3C125986CB0016D82C /* ValueObjectConstResult.cpp */, 26BC7D8410F1B77400F91463 /* ValueObjectList.h */, 26BC7E9C10F1B85900F91463 /* ValueObjectList.cpp */, 2643343A1110F63C00CDB6C6 /* ValueObjectRegister.h */, @@ -2377,6 +2383,7 @@ 4C139EA6124A8B03000BFF8D /* AppleObjCRuntimeV2.h in Headers */, 4C0A91D912511CB900CA6636 /* AppleObjCTrampolineHandler.h in Headers */, 4C0A91DB12511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h in Headers */, + 26424E3F125986D30016D82C /* ValueObjectConstResult.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2848,6 +2855,7 @@ 4C139EA5124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp in Sources */, 4C0A91D812511CB900CA6636 /* AppleObjCTrampolineHandler.cpp in Sources */, 4C0A91DA12511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */, + 26424E3D125986CB0016D82C /* ValueObjectConstResult.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 425185488f9..0b2db3328dd 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -409,3 +409,13 @@ SBFrame::GetDescription (SBStream &description) return true; } + +lldb::SBValue +SBFrame::EvaluateExpression (const char *expr) +{ + lldb::SBValue expr_result_value; + if (m_opaque_sp) + { + } + return expr_result_value; +} diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index adc8eb153eb..edcb115614f 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -206,8 +206,14 @@ CommandObjectExpression::MultiLineExpressionCallback } bool -CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream &output_stream, Stream &error_stream, - CommandReturnObject *result) +CommandObjectExpression::EvaluateExpression +( + const char *expr, + bool bare, + Stream &output_stream, + Stream &error_stream, + CommandReturnObject *result +) { if (!m_exe_ctx.process) { @@ -248,41 +254,31 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream if (expr_result) { - StreamString ss; - - if (m_options.print_object) + // TODO: seems weird to get a pointer to a result object back from + // a function. Do we own it? Feels like we do, but from looking at the + // code we don't. Might be best to make this a reference and state + // explicitly that we don't own it when we get a reference back from + // the execute? + lldb::ValueObjectSP valobj_sp (expr_result->GetExpressionResult (&m_exe_ctx)); + if (valobj_sp) { - Value result_value; - if (expr_result->PointValueAtData(result_value, &m_exe_ctx)) - { - bool obj_result; - ObjCLanguageRuntime *runtime = m_exe_ctx.process->GetObjCLanguageRuntime(); - obj_result = runtime->GetObjectDescription (ss, result_value, m_exe_ctx.GetBestExecutionContextScope()); - if (!obj_result) - { - error_stream.Printf ("Could not get object description: %s.\n", ss.GetData()); - return false; - } - // Sometimes the description doesn't have a newline on the end. For now, I'll just add one here, if - ss.Printf("\n"); - } + ValueObject::DumpValueObject (output_stream, + m_exe_ctx.GetBestExecutionContextScope(), + valobj_sp.get(), // Variable object to dump + expr_result->m_name.c_str(),// Root object name + 0, // Pointer depth to traverse (zero means stop at pointers) + 0, // Current depth, this is the top most, so zero... + UINT32_MAX, // Max depth to go when dumping concrete types, dump everything... + m_options.show_types, // Show types when dumping? + false, // Show locations of variables, no since this is a host address which we don't care to see + m_options.print_object, // Print the objective C object? + true); // Scope is already checked. Const results are always in scope. + output_stream.EOL(); } else { - Error rc = expr_result->Print (ss, - m_exe_ctx, - m_options.format, - m_options.show_types, - m_options.show_summary, - m_options.debug); - - if (rc.Fail()) { - error_stream.Printf ("Couldn't print result : %s\n", rc.AsCString()); - return false; - } + error_stream.PutCString ("Couldn't extract expression result"); } - - output_stream.PutCString(ss.GetString().c_str()); if (result) result->SetStatus (eReturnStatusSuccessFinishResult); } diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 239e1123fed..ae1cad4eaa1 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -336,125 +336,6 @@ public: return &m_options; } - void - DumpValueObject (CommandReturnObject &result, - ExecutionContextScope *exe_scope, - ValueObject *valobj, - const char *root_valobj_name, - uint32_t ptr_depth, - uint32_t curr_depth, - uint32_t max_depth, - bool use_objc, - bool scope_already_checked) - { - if (valobj) - { - Stream &s = result.GetOutputStream(); - - //const char *loc_cstr = valobj->GetLocationAsCString(); - if (m_options.show_location) - { - s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope)); - } - if (m_options.debug) - s.Printf ("%p ValueObject{%u} ", valobj, valobj->GetID()); - - s.Indent(); - - if (m_options.show_types) - s.Printf("(%s) ", valobj->GetTypeName().AsCString()); - - const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); - s.Printf ("%s = ", name_cstr); - - if (!scope_already_checked && !valobj->IsInScope(exe_scope->CalculateStackFrame())) - { - s.PutCString("error: out of scope"); - return; - } - - const char *val_cstr = valobj->GetValueAsCString(exe_scope); - const char *err_cstr = valobj->GetError().AsCString(); - - if (err_cstr) - { - s.Printf ("error: %s", err_cstr); - } - else - { - const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope); - - const bool is_aggregate = ClangASTContext::IsAggregateType (valobj->GetClangType()); - - if (val_cstr) - s.PutCString(val_cstr); - - if (sum_cstr) - s.Printf(" %s", sum_cstr); - - if (use_objc) - { - const char *object_desc = valobj->GetObjectDescription(exe_scope); - if (object_desc) - s.Printf("\n%s\n", object_desc); - else - s.Printf ("No description available.\n"); - return; - } - - - if (curr_depth < max_depth) - { - if (is_aggregate) - s.PutChar('{'); - - bool is_ptr_or_ref = ClangASTContext::IsPointerOrReferenceType (valobj->GetClangType()); - - if (is_ptr_or_ref && ptr_depth == 0) - return; - - const uint32_t num_children = valobj->GetNumChildren(); - if (num_children) - { - s.IndentMore(); - for (uint32_t idx=0; idx<num_children; ++idx) - { - ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true)); - if (child_sp.get()) - { - s.EOL(); - DumpValueObject (result, - exe_scope, - child_sp.get(), - NULL, - is_ptr_or_ref ? ptr_depth - 1 : ptr_depth, - curr_depth + 1, - max_depth, - false, - true); - if (idx + 1 < num_children) - s.PutChar(','); - } - } - s.IndentLess(); - } - if (is_aggregate) - { - s.EOL(); - s.Indent("}"); - } - } - else - { - if (is_aggregate) - { - s.PutCString("{...}"); - } - } - - } - } - } virtual bool Execute @@ -517,16 +398,17 @@ public: s.PutCString (": "); } - DumpValueObject (result, - exe_ctx.frame, - valobj_sp.get(), - name_cstr, - m_options.ptr_depth, - 0, - m_options.max_depth, - m_options.use_objc, - false); - + ValueObject::DumpValueObject (result.GetOutputStream(), + exe_ctx.frame, + valobj_sp.get(), + name_cstr, + m_options.ptr_depth, + 0, + m_options.max_depth, + m_options.show_types, + m_options.show_location, + m_options.use_objc, + false); s.EOL(); } } @@ -683,15 +565,18 @@ public: s.PutCString (": "); } - DumpValueObject (result, - exe_ctx.frame, - valobj_sp.get(), - name_cstr, - ptr_depth, - 0, - m_options.max_depth, - m_options.use_objc, - false); + + ValueObject::DumpValueObject (result.GetOutputStream(), + exe_ctx.frame, + valobj_sp.get(), + name_cstr, + ptr_depth, + 0, + m_options.max_depth, + m_options.show_types, + m_options.show_location, + m_options.use_objc, + false); s.EOL(); } @@ -762,16 +647,18 @@ public: var_sp->GetDeclaration ().DumpStopContext (&s, false); s.PutCString (": "); } - DumpValueObject (result, - exe_ctx.frame, - valobj_sp.get(), - name_cstr, - m_options.ptr_depth, - 0, - m_options.max_depth, - m_options.use_objc, - true); - + ValueObject::DumpValueObject (result.GetOutputStream(), + exe_ctx.frame, + valobj_sp.get(), + name_cstr, + m_options.ptr_depth, + 0, + m_options.max_depth, + m_options.show_types, + m_options.show_location, + m_options.use_objc, + false); + s.EOL(); } } diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp index 3ae4bec76a2..e75a1c6738b 100644 --- a/lldb/source/Core/DataExtractor.cpp +++ b/lldb/source/Core/DataExtractor.cpp @@ -93,7 +93,7 @@ DataExtractor::DataExtractor (const void* data, uint32_t length, ByteOrder endia // as long as any DataExtractor objects exist that have a reference to // this data. //---------------------------------------------------------------------- -DataExtractor::DataExtractor (DataBufferSP& data_sp, ByteOrder endian, uint8_t addr_size) : +DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uint8_t addr_size) : m_start (NULL), m_end (NULL), m_byte_order(endian), @@ -370,7 +370,7 @@ DataExtractor::SetData (const DataExtractor& data, uint32_t data_offset, uint32_ // settings will remain unchanged from their current settings. //---------------------------------------------------------------------- uint32_t -DataExtractor::SetData (DataBufferSP& data_sp, uint32_t data_offset, uint32_t data_length) +DataExtractor::SetData (const DataBufferSP& data_sp, uint32_t data_offset, uint32_t data_length) { m_start = m_end = NULL; diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index ae53a838af5..4b7f0d70807 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -851,3 +851,127 @@ ValueObject::SetDynamicValue () return true; } + + +void +ValueObject::DumpValueObject +( + Stream &s, + ExecutionContextScope *exe_scope, + ValueObject *valobj, + const char *root_valobj_name, + uint32_t ptr_depth, + uint32_t curr_depth, + uint32_t max_depth, + bool show_types, + bool show_location, + bool use_objc, + bool scope_already_checked +) +{ + if (valobj) + { + //const char *loc_cstr = valobj->GetLocationAsCString(); + if (show_location) + { + s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope)); + } + + s.Indent(); + + if (show_types) + s.Printf("(%s) ", valobj->GetTypeName().AsCString()); + + const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); + s.Printf ("%s = ", name_cstr); + + if (!scope_already_checked && !valobj->IsInScope(exe_scope->CalculateStackFrame())) + { + s.PutCString("error: out of scope"); + return; + } + + const char *val_cstr = valobj->GetValueAsCString(exe_scope); + const char *err_cstr = valobj->GetError().AsCString(); + + if (err_cstr) + { + s.Printf ("error: %s", err_cstr); + } + else + { + const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope); + + const bool is_aggregate = ClangASTContext::IsAggregateType (valobj->GetClangType()); + + if (val_cstr) + s.PutCString(val_cstr); + + if (sum_cstr) + s.Printf(" %s", sum_cstr); + + if (use_objc) + { + const char *object_desc = valobj->GetObjectDescription(exe_scope); + if (object_desc) + s.Printf("\n%s\n", object_desc); + else + s.Printf ("No description available.\n"); + return; + } + + + if (curr_depth < max_depth) + { + if (is_aggregate) + s.PutChar('{'); + + bool is_ptr_or_ref = ClangASTContext::IsPointerOrReferenceType (valobj->GetClangType()); + + if (is_ptr_or_ref && ptr_depth == 0) + return; + + const uint32_t num_children = valobj->GetNumChildren(); + if (num_children) + { + s.IndentMore(); + for (uint32_t idx=0; idx<num_children; ++idx) + { + ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true)); + if (child_sp.get()) + { + s.EOL(); + DumpValueObject (s, + exe_scope, + child_sp.get(), + NULL, + is_ptr_or_ref ? ptr_depth - 1 : ptr_depth, + curr_depth + 1, + max_depth, + show_types, + show_location, + false, + true); + if (idx + 1 < num_children) + s.PutChar(','); + } + } + s.IndentLess(); + } + if (is_aggregate) + { + s.EOL(); + s.Indent("}"); + } + } + else + { + if (is_aggregate) + { + s.PutCString("{...}"); + } + } + } + } +} + diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp new file mode 100644 index 00000000000..d2317dfde41 --- /dev/null +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -0,0 +1,109 @@ +//===-- ValueObjectConstResult.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/ValueObjectConstResult.h" + +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ValueObjectList.h" + +#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Symbol/Variable.h" + +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +ValueObjectConstResult::ValueObjectConstResult +( + clang::ASTContext *clang_ast, + void *clang_type, + const ConstString &name, + const lldb::DataBufferSP &data_sp, + lldb::ByteOrder data_byte_order, + uint8_t data_addr_size +) : + ValueObject (), + m_clang_ast (clang_ast), + m_type_name () +{ + m_data.SetByteOrder(data_byte_order); + m_data.SetAddressByteSize(data_addr_size); + m_data.SetData(data_sp); + m_value.GetScalar() = (uintptr_t)data_sp->GetBytes(); + m_value.SetValueType(Value::eValueTypeHostAddress); + m_value.SetContext(Value::eContextTypeOpaqueClangQualType, clang_type); + m_name = name; +} + +ValueObjectConstResult::~ValueObjectConstResult() +{ +} + +void * +ValueObjectConstResult::GetClangType() +{ + return m_value.GetClangType(); +} + +lldb::ValueType +ValueObjectConstResult::GetValueType() const +{ + return eValueTypeConstResult; +} + +size_t +ValueObjectConstResult::GetByteSize() +{ + // We stored all the data for this const object in our data + return m_data.GetByteSize(); +} + +uint32_t +ValueObjectConstResult::CalculateNumChildren() +{ + return ClangASTContext::GetNumChildren (GetClangType(), true); +} + +clang::ASTContext * +ValueObjectConstResult::GetClangAST () +{ + return m_clang_ast; +} + +ConstString +ValueObjectConstResult::GetTypeName() +{ + if (m_type_name.IsEmpty()) + m_type_name = ClangASTType::GetClangTypeName (GetClangType()); + return m_type_name; +} + +void +ValueObjectConstResult::UpdateValue (ExecutionContextScope *exe_scope) +{ + m_error.Clear(); + // Const value is always valid + SetValueIsValid (true); +} + + +bool +ValueObjectConstResult::IsInScope (StackFrame *frame) +{ + // A const result value is always in scope since it serializes all + // information needed to contain the constant value. + return true; +} diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 2c244bda95f..3c8476460bb 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -575,10 +575,10 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize, size_t pvar_size = pvar->Size(); - if (!pvar->m_data_vars.get()) + if (!pvar->m_data_sp.get()) return false; - uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes(); + uint8_t *pvar_data = pvar->m_data_sp->GetBytes(); Error error; if (dematerialize) diff --git a/lldb/source/Expression/ClangExpressionVariable.cpp b/lldb/source/Expression/ClangExpressionVariable.cpp index 0ae37e488cd..d6798f563cc 100644 --- a/lldb/source/Expression/ClangExpressionVariable.cpp +++ b/lldb/source/Expression/ClangExpressionVariable.cpp @@ -18,154 +18,74 @@ #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Stream.h" #include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" using namespace lldb_private; using namespace clang; -ClangExpressionVariable::ClangExpressionVariable() +ClangExpressionVariable::ClangExpressionVariable() : + m_name(), + m_user_type (TypeFromUser(NULL, NULL)), + m_store (NULL), + m_index (0), + m_parser_vars(), + m_jit_vars (), + m_data_sp () { - m_name = ""; - m_user_type = TypeFromUser(NULL, NULL); - m_parser_vars.reset(NULL); - m_jit_vars.reset(NULL); - m_data_vars.reset(NULL); } -void ClangExpressionVariable::DisableDataVars() +void +ClangExpressionVariable::DisableDataVars() { - if (m_data_vars.get() && m_data_vars->m_data) - delete m_data_vars->m_data; - m_data_vars.reset(); + m_data_sp.reset(); } -Error -ClangExpressionVariable::Print (Stream &output_stream, - ExecutionContext &exe_ctx, - lldb::Format format, - bool show_types, - bool show_summary, - bool verbose) -{ - Error err; - - Value val; - if (!PointValueAtData (val, NULL)) - { - err.SetErrorToGenericError(); - err.SetErrorStringWithFormat("Variable doesn't contain a value"); - return err; - } - - if (val.GetContextType () == Value::eContextTypeInvalid && - val.GetValueType () == Value::eValueTypeScalar && - format == lldb::eFormatDefault) - { - // The expression result is just a scalar with no special formatting - val.GetScalar ().GetValue (&output_stream, show_types); - output_stream.EOL (); - return err; - } - - clang::ASTContext *ast_context = m_user_type.GetASTContext(); - // The expression result is more complex and requires special handling - DataExtractor data; - Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0); - - - // Set byte order and pointer size to TARGET byte order and pointer size! - - data.SetByteOrder(exe_ctx.process->GetByteOrder()); - data.SetAddressByteSize(exe_ctx.process->GetAddressByteSize()); - - if (!expr_error.Success ()) - { - err.SetErrorToGenericError (); - err.SetErrorStringWithFormat ("Couldn't resolve variable value: %s", expr_error.AsCString ()); - return err; - } - - if (format == lldb::eFormatDefault) - format = val.GetValueDefaultFormat (); - - void *clang_type = val.GetClangType (); - - output_stream.Printf("%s = ", m_name.c_str()); - - if (clang_type) - { - if (show_types) - output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString()); - - ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to - clang_type, // The opaque clang type we want to dump that value of - &exe_ctx, // The execution context for memory and variable access - &output_stream, // Stream to dump to - format, // Format to use when dumping - data, // A buffer containing the bytes for the clang type - 0, // Byte offset within "data" where value is - data.GetByteSize (), // Size in bytes of the value we are dumping - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, // Show types? - show_summary, // Show summary? - verbose, // Debug logging output? - UINT32_MAX); // Depth to dump in case this is an aggregate type - } - else - { - data.Dump (&output_stream, // Stream to dump to - 0, // Byte offset within "data" - format, // Format to use when dumping - data.GetByteSize (), // Size in bytes of each item we are dumping - 1, // Number of items to dump - UINT32_MAX, // Number of items per line - LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context - 0, // Bitfield bit size - 0); // Bitfield bit offset - } - - output_stream.EOL(); - - return err; -} - -ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &cev) : - m_name(cev.m_name), - m_user_type(cev.m_user_type), - m_store(cev.m_store), - m_index(cev.m_index) +ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &rhs) : + m_name(rhs.m_name), + m_user_type(rhs.m_user_type), + m_store(rhs.m_store), + m_index(rhs.m_index) { - if (cev.m_parser_vars.get()) + if (rhs.m_parser_vars.get()) { + // TODO: Sean, can m_parser_vars be a shared pointer??? We are copy + // constructing it here. That is ok if we need to, but do we really + // need to? m_parser_vars.reset(new struct ParserVars); - *m_parser_vars.get() = *cev.m_parser_vars.get(); + *m_parser_vars.get() = *rhs.m_parser_vars.get(); } - if (cev.m_jit_vars.get()) + if (rhs.m_jit_vars.get()) { + // TODO: Sean, can m_jit_vars be a shared pointer??? We are copy + // constructing it here. That is ok if we need to, but do we really + // need to? m_jit_vars.reset(new struct JITVars); - *m_jit_vars.get() = *cev.m_jit_vars.get(); + *m_jit_vars.get() = *rhs.m_jit_vars.get(); } - if (cev.m_data_vars.get()) + if (rhs.m_data_sp) { - m_data_vars.reset(new struct DataVars); - *m_data_vars.get() = *cev.m_data_vars.get(); + // TODO: Sean, does m_data_sp need to be copy constructed? Or can it + // shared the data? + + m_data_sp.reset(new DataBufferHeap (rhs.m_data_sp->GetBytes(), + rhs.m_data_sp->GetByteSize())); } } bool ClangExpressionVariable::PointValueAtData(Value &value, ExecutionContext *exe_ctx) { - if (!m_data_vars.get() || !m_data_vars->m_data) + if (m_data_sp.get() == NULL) return false; value.SetContext(Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType()); value.SetValueType(Value::eValueTypeHostAddress); - value.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes(); + value.GetScalar() = (uintptr_t)m_data_sp->GetBytes(); clang::ASTContext *ast_context = m_user_type.GetASTContext(); if (exe_ctx) @@ -173,3 +93,46 @@ ClangExpressionVariable::PointValueAtData(Value &value, ExecutionContext *exe_ct return true; } + +void +ClangExpressionVariable::EnableDataVars() +{ + if (!m_data_sp.get()) + m_data_sp.reset(new DataBufferHeap); +} + +lldb::ValueObjectSP +ClangExpressionVariable::GetExpressionResult (ExecutionContext *exe_ctx) +{ + lldb::ValueObjectSP result_sp; + if (m_data_sp) + { + Target * target = NULL; + Process *process = NULL; + if (exe_ctx) + { + target = exe_ctx->target; + process = exe_ctx->process; + } + + Value value; + if (PointValueAtData(value, exe_ctx)) + { + lldb::ByteOrder byte_order = lldb::eByteOrderHost; + uint32_t addr_byte_size = 4; + if (process) + { + byte_order = process->GetByteOrder(); + addr_byte_size = process->GetAddressByteSize(); + } + result_sp.reset (new ValueObjectConstResult (m_user_type.GetASTContext(), + m_user_type.GetOpaqueQualType(), + ConstString (m_name.c_str()), + m_data_sp,// TODO: sean can you get this to be valid? + byte_order, + addr_byte_size)); + } + } + return result_sp; +} + diff --git a/lldb/source/Expression/ClangPersistentVariables.cpp b/lldb/source/Expression/ClangPersistentVariables.cpp index f014811fb17..49674a9d8ae 100644 --- a/lldb/source/Expression/ClangPersistentVariables.cpp +++ b/lldb/source/Expression/ClangPersistentVariables.cpp @@ -33,8 +33,8 @@ ClangPersistentVariables::GetNextResultName (std::string &name) } bool -ClangPersistentVariables::CreatePersistentVariable(const char *name, - TypeFromUser user_type) +ClangPersistentVariables::CreatePersistentVariable(const char *name, + TypeFromUser user_type) { if (GetVariable(name)) return false; @@ -43,10 +43,11 @@ ClangPersistentVariables::CreatePersistentVariable(const char *name, pvar.m_name = name; pvar.m_user_type = user_type; - - pvar.EnableDataVars(); - - pvar.m_data_vars->m_data = new DataBufferHeap(pvar.Size(), 0); + // TODO: Sean, why do we need to call this?, we can just make it below + // and we aren't checking the result or anything... Is this cruft left + // over from an old code re-org? + //pvar.EnableDataVars(); + pvar.m_data_sp.reset(new DataBufferHeap(pvar.Size(), 0)); return true; }
\ No newline at end of file |