Fixed ClangUserExpression's wrapping of expressions

in C++ methods.  There were two fixes involved:

 - For an object whose contents are not known, the
   expression should be treated as a non-member, and
   "this" should have no meaning.

 - For a const object, the method should be declared
   const as well.

llvm-svn: 120606
This commit is contained in:
Sean Callanan 2010-12-01 21:35:54 +00:00
parent 9d0bb1e366
commit 3670ba5c87
4 changed files with 48 additions and 5 deletions

View File

@ -272,6 +272,7 @@ private:
bool m_cplusplus; ///< True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was in a C++ method).
bool m_objectivec; ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method).
bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and passed in. False if the expression doesn't really use them and they can be NULL.
bool m_const_object; ///< True if "this" is const.
};
} // namespace lldb_private

View File

@ -196,6 +196,12 @@ public:
static bool
IsDefined (lldb::clang_type_t opaque_clang_qual_type);
bool
IsConst();
static bool
IsConst (lldb::clang_type_t opaque_clang_qual_type);
bool
SetValueFromScalar (const Scalar &value,
Stream &strm);

View File

@ -47,6 +47,7 @@ ClangUserExpression::ClangUserExpression (const char *expr,
m_cplusplus(false),
m_objectivec(false),
m_needs_object_ptr(false),
m_const_object(false),
m_desired_type(NULL, NULL)
{
}
@ -73,10 +74,31 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx)
if (!vars)
return;
if (vars->FindVariable(ConstString("this")).get())
m_cplusplus = true;
else if (vars->FindVariable(ConstString("self")).get())
lldb::VariableSP this_var(vars->FindVariable(ConstString("this")));
lldb::VariableSP self_var(vars->FindVariable(ConstString("self")));
if (this_var.get())
{
Type *this_type = this_var->GetType();
lldb::clang_type_t pointer_target_type;
if (ClangASTContext::IsPointerType(this_type->GetClangType(),
&pointer_target_type))
{
TypeFromUser target_ast_type(pointer_target_type, this_type->GetClangAST());
if (target_ast_type.IsDefined())
m_cplusplus = true;
if (target_ast_type.IsConst())
m_const_object = true;
}
}
else if (self_var.get())
{
m_objectivec = true;
}
}
// This is a really nasty hack, meant to fix Objective-C expressions of the form
@ -141,12 +163,13 @@ ClangUserExpression::Parse (Stream &error_stream,
m_transformed_stream.Printf("%s \n"
"typedef unsigned short unichar; \n"
"void \n"
"$__lldb_class::%s(void *$__lldb_arg) \n"
"$__lldb_class::%s(void *$__lldb_arg) %s\n"
"{ \n"
" %s; \n"
"} \n",
m_expr_prefix.c_str(),
FunctionName(),
(m_const_object ? "const" : ""),
m_expr_text.c_str());
m_needs_object_ptr = true;

View File

@ -812,7 +812,6 @@ ClangASTType::IsDefined()
return ClangASTType::IsDefined (m_type);
}
bool
ClangASTType::IsDefined (clang_type_t clang_type)
{
@ -838,6 +837,20 @@ ClangASTType::IsDefined (clang_type_t clang_type)
return true;
}
bool
ClangASTType::IsConst()
{
return ClangASTType::IsConst (m_type);
}
bool
ClangASTType::IsConst (lldb::clang_type_t clang_type)
{
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
return qual_type.isConstQualified();
}
void
ClangASTType::DumpTypeDescription (Stream *s)
{