Import block pointers from DWARF as Clang block pointers, not as structs.
Also added a data formatter that presents them as structs if you use frame
variable to look at their contents. Now the blocks testcase works.
<rdar://problem/15984431>
llvm-svn: 268307
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 6b61646..5905a9a 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -89,6 +89,7 @@
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
@@ -2044,6 +2045,13 @@
function_decl->setParams (ArrayRef<ParmVarDecl*>(params, num_params));
}
+CompilerType
+ClangASTContext::CreateBlockPointerType (const CompilerType &function_type)
+{
+ QualType block_type = m_ast_ap->getBlockPointerType(clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));
+
+ return CompilerType (this, block_type.getAsOpaquePtr());
+}
#pragma mark Array Types
@@ -2081,13 +2089,17 @@
}
CompilerType
-ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
- const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
- bool packed)
+ClangASTContext::CreateStructForIdentifier (const ConstString &type_name,
+ const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
+ bool packed)
{
CompilerType type;
- if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ if (!type_name.IsEmpty() && (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ {
+ lldbassert("Trying to create a type for an existing name");
return type;
+ }
+
type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
StartTagDeclarationDefinition(type);
for (const auto& field : type_fields)
@@ -2098,6 +2110,20 @@
return type;
}
+CompilerType
+ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
+ const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
+ bool packed)
+{
+ CompilerType type;
+ if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ return type;
+
+ return CreateStructForIdentifier (type_name,
+ type_fields,
+ packed);
+}
+
#pragma mark Enumeration Types
CompilerType
@@ -3177,6 +3203,52 @@
}
bool
+ClangASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
+{
+ if (type)
+ {
+ clang::QualType qual_type (GetCanonicalQualType(type));
+
+ if (qual_type->isBlockPointerType())
+ {
+ if (function_pointer_type_ptr)
+ {
+ const clang::BlockPointerType *block_pointer_type = qual_type->getAs<clang::BlockPointerType>();
+ QualType pointee_type = block_pointer_type->getPointeeType();
+ QualType function_pointer_type = m_ast_ap->getPointerType(pointee_type);
+ *function_pointer_type_ptr = CompilerType (getASTContext(), function_pointer_type);
+ }
+ return true;
+ }
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ default:
+ break;
+ case clang::Type::Typedef:
+ return IsBlockPointerType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), function_pointer_type_ptr);
+ case clang::Type::Auto:
+ return IsBlockPointerType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), function_pointer_type_ptr);
+ case clang::Type::Elaborated:
+ return IsBlockPointerType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), function_pointer_type_ptr);
+ case clang::Type::Paren:
+ return IsBlockPointerType (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), function_pointer_type_ptr);
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ {
+ const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return IsBlockPointerType(reference_type->getPointeeType().getAsOpaquePtr(), function_pointer_type_ptr);
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+bool
ClangASTContext::IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed)
{
if (!type)