<rdar://problem/12928282>
Added SBTarget::EvaluateExpression() so expressions can be evaluated without needing a process.
Also fixed many functions that deal with clang AST types to be able to properly handle the clang::Type::Elaborated types ("struct foo", "class bar").
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@171476 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/API/SBExpressionOptions.h b/include/lldb/API/SBExpressionOptions.h
index 97e42c0..f3dce3c 100644
--- a/include/lldb/API/SBExpressionOptions.h
+++ b/include/lldb/API/SBExpressionOptions.h
@@ -20,9 +20,6 @@
class SBExpressionOptions
{
-friend class SBFrame;
-friend class SBValue;
-
public:
SBExpressionOptions();
@@ -73,6 +70,10 @@
lldb_private::EvaluateExpressionOptions &
ref () const;
+ friend class SBFrame;
+ friend class SBValue;
+ friend class SBTarget;
+
private:
// This auto_pointer is made in the constructor and is always valid.
mutable std::auto_ptr<lldb_private::EvaluateExpressionOptions> m_opaque_ap;
diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h
index cdcc86f..ddc868a 100644
--- a/include/lldb/API/SBTarget.h
+++ b/include/lldb/API/SBTarget.h
@@ -17,6 +17,7 @@
#include "lldb/API/SBFileSpecList.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/API/SBType.h"
+#include "lldb/API/SBValue.h"
#include "lldb/API/SBWatchpoint.h"
namespace lldb {
@@ -748,6 +749,9 @@
bool
GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);
+ lldb::SBValue
+ EvaluateExpression (const char *expr, const SBExpressionOptions &options);
+
protected:
friend class SBAddress;
friend class SBBlock;
diff --git a/include/lldb/API/SBValue.h b/include/lldb/API/SBValue.h
index 7b0a646..91cf638 100644
--- a/include/lldb/API/SBValue.h
+++ b/include/lldb/API/SBValue.h
@@ -419,6 +419,7 @@
protected:
friend class SBBlock;
friend class SBFrame;
+ friend class SBTarget;
friend class SBThread;
friend class SBValueList;
diff --git a/scripts/Python/interface/SBTarget.i b/scripts/Python/interface/SBTarget.i
index 8b23dda..88fcf03 100644
--- a/scripts/Python/interface/SBTarget.i
+++ b/scripts/Python/interface/SBTarget.i
@@ -697,6 +697,8 @@
bool
GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);
+ lldb::SBValue
+ EvaluateExpression (const char *expr, const lldb::SBExpressionOptions &options);
%pythoncode %{
class modules_access(object):
'''A helper object that will lazily hand out lldb.SBModule objects for a target when supplied an index, or by full or partial path.'''
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index c6c4f72..4641437 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -15,6 +15,7 @@
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBModule.h"
@@ -2464,3 +2465,73 @@
}
+lldb::SBValue
+SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &options)
+{
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ LogSP expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ SBValue expr_result;
+ ExecutionResults exe_results = eExecutionSetupError;
+ ValueObjectSP expr_value_sp;
+ TargetSP target_sp(GetSP());
+ StackFrame *frame = NULL;
+ if (target_sp)
+ {
+ if (expr == NULL || expr[0] == '\0')
+ {
+ if (log)
+ log->Printf ("SBTarget::EvaluateExpression called with an empty expression");
+ return expr_result;
+ }
+
+ Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ ExecutionContext exe_ctx (m_opaque_sp.get());
+
+ if (log)
+ log->Printf ("SBTarget()::EvaluateExpression (expr=\"%s\")...", expr);
+
+ frame = exe_ctx.GetFramePtr();
+ Target *target = exe_ctx.GetTargetPtr();
+
+ if (target)
+ {
+#ifdef LLDB_CONFIGURATION_DEBUG
+ StreamString frame_description;
+ if (frame)
+ frame->DumpUsingSettingsFormat (&frame_description);
+ Host::SetCrashDescriptionWithFormat ("SBTarget::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
+ expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str());
+#endif
+ exe_results = target->EvaluateExpression (expr,
+ frame,
+ expr_value_sp,
+ options.ref());
+
+ expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
+#ifdef LLDB_CONFIGURATION_DEBUG
+ Host::SetCrashDescription (NULL);
+#endif
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBTarget::EvaluateExpression () => error: could not reconstruct frame object for this SBTarget.");
+ }
+ }
+#ifndef LLDB_DISABLE_PYTHON
+ if (expr_log)
+ expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is %s, summary %s **",
+ expr_result.GetValue(),
+ expr_result.GetSummary());
+
+ if (log)
+ log->Printf ("SBTarget(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)",
+ frame,
+ expr,
+ expr_value_sp.get(),
+ exe_results);
+#endif
+
+ return expr_result;
+}
+
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 59c97c4..60be93f 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -2793,6 +2793,10 @@
case clang::Type::Typedef:
return ClangASTContext::GetNumTemplateArguments (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+
+ case clang::Type::Elaborated:
+ return ClangASTContext::GetNumTemplateArguments (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+
default:
break;
}
@@ -2866,6 +2870,10 @@
case clang::Type::Typedef:
return ClangASTContext::GetTemplateArgument (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), arg_idx, kind);
+
+ case clang::Type::Elaborated:
+ return ClangASTContext::GetTemplateArgument (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), arg_idx, kind);
+
default:
break;
}
@@ -4750,6 +4758,13 @@
omit_empty_base_classes,
child_indexes);
+ case clang::Type::Elaborated:
+ return GetIndexOfChildMemberWithName (ast,
+ cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ name,
+ omit_empty_base_classes,
+ child_indexes);
+
default:
break;
}
@@ -4957,6 +4972,12 @@
}
break;
+ case clang::Type::Elaborated:
+ return GetIndexOfChildWithName (ast,
+ cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ name,
+ omit_empty_base_classes);
+
case clang::Type::Typedef:
return GetIndexOfChildWithName (ast,
cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
diff --git a/source/Symbol/ClangASTType.cpp b/source/Symbol/ClangASTType.cpp
index 642819e..84ea29a 100644
--- a/source/Symbol/ClangASTType.cpp
+++ b/source/Symbol/ClangASTType.cpp
@@ -250,7 +250,9 @@
case clang::Type::Typedef: return lldb::eTypeClassTypedef;
case clang::Type::UnresolvedUsing: break;
case clang::Type::Paren: break;
- case clang::Type::Elaborated: break;
+ case clang::Type::Elaborated:
+ return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+
case clang::Type::Attributed: break;
case clang::Type::TemplateTypeParm: break;
case clang::Type::SubstTemplateTypeParm: break;
@@ -455,14 +457,15 @@
case clang::Type::Record: break;
case clang::Type::Enum: return lldb::eEncodingSint;
case clang::Type::Typedef:
- return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
- break;
+ return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
+
+ case clang::Type::Elaborated:
+ return ClangASTType::GetEncoding (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), count);
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
case clang::Type::Paren:
- case clang::Type::Elaborated:
case clang::Type::Attributed:
case clang::Type::TemplateTypeParm:
case clang::Type::SubstTemplateTypeParm:
@@ -581,15 +584,15 @@
case clang::Type::Record: break;
case clang::Type::Enum: return lldb::eFormatEnum;
case clang::Type::Typedef:
- return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-
+ return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
case clang::Type::Auto:
- return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
+ return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
+ case clang::Type::Elaborated:
+ return ClangASTType::GetFormat(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
case clang::Type::Paren:
- case clang::Type::Elaborated:
case clang::Type::Attributed:
case clang::Type::TemplateTypeParm:
case clang::Type::SubstTemplateTypeParm:
@@ -914,6 +917,29 @@
}
break;
+ case clang::Type::Elaborated:
+ {
+ clang::QualType elaborated_qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
+ lldb::Format elaborated_format = ClangASTType::GetFormat(elaborated_qual_type.getAsOpaquePtr());
+ std::pair<uint64_t, unsigned> elaborated_type_info = ast_context->getTypeInfo(elaborated_qual_type);
+ uint64_t elaborated_byte_size = elaborated_type_info.first / 8;
+
+ return DumpValue (ast_context, // The clang AST context for this type
+ elaborated_qual_type.getAsOpaquePtr(), // The clang type we want to dump
+ exe_ctx,
+ s, // Stream to dump to
+ elaborated_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ elaborated_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset,// Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
+ }
+ break;
default:
// We are down the a scalar type that we just need to display.
data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset);
@@ -1305,6 +1331,12 @@
}
break;
+ case clang::Type::Elaborated:
+ DumpTypeDescription (ast_context,
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ s);
+ return;
+
case clang::Type::Record:
if (ClangASTContext::GetCompleteType (ast_context, clang_type))
{