[Core] Generalize ValueObject::MaybeCalculateCompleteType

Summary:
Instead of hardcoding ClangASTContext and ObjCLanguageRuntime, we can
generalize this by creating the method GetRuntimeType in
LanguageRuntime and moving the current MaybeCalculateCompleteType
implementation into ObjCLanguageruntime::GetRuntimeType

Reviewers: jingham, clayborg, JDevlieghere

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D64159

llvm-svn: 365939
This commit is contained in:
Alex Langford 2019-07-12 18:34:37 +00:00
parent cb5ecae1f6
commit 24604ec799
4 changed files with 52 additions and 42 deletions

View File

@ -156,6 +156,10 @@ public:
/// from the user interface.
virtual bool IsWhitelistedRuntimeValue(ConstString name) { return false; }
virtual llvm::Optional<CompilerType> GetRuntimeType(CompilerType base_type) {
return llvm::None;
}
virtual void ModulesDidLoad(const ModuleList &module_list) {}
// Called by the Clang expression evaluation engine to allow runtimes to

View File

@ -250,6 +250,8 @@ public:
lldb::TypeSP LookupInCompleteClassCache(ConstString &name);
llvm::Optional<CompilerType> GetRuntimeType(CompilerType base_type) override;
virtual UtilityFunction *CreateObjectChecker(const char *) = 0;
virtual ObjCRuntimeVersions GetRuntimeVersion() const {

View File

@ -35,7 +35,6 @@
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
@ -280,51 +279,21 @@ CompilerType ValueObject::MaybeCalculateCompleteType() {
return compiler_type;
}
CompilerType class_type;
bool is_pointer_type = false;
if (ClangASTContext::IsObjCObjectPointerType(compiler_type, &class_type)) {
is_pointer_type = true;
} else if (ClangASTContext::IsObjCObjectOrInterfaceType(compiler_type)) {
class_type = compiler_type;
} else {
return compiler_type;
}
m_did_calculate_complete_objc_class_type = true;
if (class_type) {
ConstString class_name(class_type.GetConstTypeName());
ProcessSP process_sp(
GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
if (class_name) {
ProcessSP process_sp(
GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
if (!process_sp)
return compiler_type;
if (process_sp) {
ObjCLanguageRuntime *objc_language_runtime(
ObjCLanguageRuntime::Get(*process_sp));
if (objc_language_runtime) {
TypeSP complete_objc_class_type_sp =
objc_language_runtime->LookupInCompleteClassCache(class_name);
if (complete_objc_class_type_sp) {
CompilerType complete_class(
complete_objc_class_type_sp->GetFullCompilerType());
if (complete_class.GetCompleteType()) {
if (is_pointer_type) {
m_override_type = complete_class.GetPointerType();
} else {
m_override_type = complete_class;
}
if (m_override_type.IsValid())
return m_override_type;
}
}
}
}
if (auto *runtime =
process_sp->GetLanguageRuntime(GetObjectRuntimeLanguage())) {
if (llvm::Optional<CompilerType> complete_type =
runtime->GetRuntimeType(compiler_type)) {
m_override_type = complete_type.getValue();
if (m_override_type.IsValid())
return m_override_type;
}
}
return compiler_type;

View File

@ -398,3 +398,38 @@ Status ObjCLanguageRuntime::ObjCExceptionPrecondition::ConfigurePrecondition(
"The ObjC Exception breakpoint doesn't support extra options.");
return error;
}
llvm::Optional<CompilerType>
ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) {
CompilerType class_type;
bool is_pointer_type = false;
if (ClangASTContext::IsObjCObjectPointerType(base_type, &class_type))
is_pointer_type = true;
else if (ClangASTContext::IsObjCObjectOrInterfaceType(base_type))
class_type = base_type;
else
return llvm::None;
if (!class_type)
return llvm::None;
ConstString class_name(class_type.GetConstTypeName());
if (!class_name)
return llvm::None;
TypeSP complete_objc_class_type_sp = LookupInCompleteClassCache(class_name);
if (!complete_objc_class_type_sp)
return llvm::None;
CompilerType complete_class(
complete_objc_class_type_sp->GetFullCompilerType());
if (complete_class.GetCompleteType()) {
if (is_pointer_type)
return complete_class.GetPointerType();
else
return complete_class;
}
return llvm::None;
}