forked from OSchip/llvm-project
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
This commit is contained in:
parent
52f8693263
commit
c530ba98a9
|
@ -302,6 +302,11 @@ public:
|
|||
return compiler_type;
|
||||
}
|
||||
|
||||
CompilerType
|
||||
CreateStructForIdentifier (const ConstString &type_name,
|
||||
const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
|
||||
bool packed = false);
|
||||
|
||||
CompilerType
|
||||
GetOrCreateStructForIdentifier (const ConstString &type_name,
|
||||
const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
|
||||
|
@ -477,6 +482,9 @@ public:
|
|||
clang::ParmVarDecl **params,
|
||||
unsigned num_params);
|
||||
|
||||
CompilerType
|
||||
CreateBlockPointerType (const CompilerType &function_type);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Array Types
|
||||
//------------------------------------------------------------------
|
||||
|
@ -682,6 +690,9 @@ public:
|
|||
bool
|
||||
IsFunctionPointerType (lldb::opaque_compiler_type_t type) override;
|
||||
|
||||
bool
|
||||
IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override;
|
||||
|
||||
bool
|
||||
IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) override;
|
||||
|
||||
|
|
|
@ -148,6 +148,9 @@ public:
|
|||
bool
|
||||
IsFunctionPointerType () const;
|
||||
|
||||
bool
|
||||
IsBlockPointerType (CompilerType *function_pointer_type_ptr) const;
|
||||
|
||||
bool
|
||||
IsIntegerType (bool &is_signed) const;
|
||||
|
||||
|
|
|
@ -177,6 +177,8 @@ class GoASTContext : public TypeSystem
|
|||
|
||||
bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;
|
||||
|
||||
bool IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override;
|
||||
|
||||
bool IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override;
|
||||
|
||||
bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
|
||||
|
|
|
@ -122,6 +122,9 @@ public:
|
|||
bool
|
||||
IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;
|
||||
|
||||
bool
|
||||
IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override;
|
||||
|
||||
bool
|
||||
IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override;
|
||||
|
||||
|
|
|
@ -209,6 +209,9 @@ public:
|
|||
virtual bool
|
||||
IsFunctionPointerType (lldb::opaque_compiler_type_t type) = 0;
|
||||
|
||||
virtual bool
|
||||
IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) = 0;
|
||||
|
||||
virtual bool
|
||||
IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) = 0;
|
||||
|
||||
|
|
|
@ -693,6 +693,8 @@
|
|||
49DA65031485C92A005FF180 /* AppleObjCDeclVendor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA65021485C92A005FF180 /* AppleObjCDeclVendor.cpp */; };
|
||||
49DCF6FE170E6B4A0092F75E /* IRMemoryMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF6FD170E6B4A0092F75E /* IRMemoryMap.cpp */; };
|
||||
49DCF702170E70120092F75E /* Materializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF700170E70120092F75E /* Materializer.cpp */; };
|
||||
49DEF1221CD7BD90006A7C7D /* BlockPointer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 49DEF1201CD7BD90006A7C7D /* BlockPointer.h */; };
|
||||
49DEF1251CD7C6DF006A7C7D /* BlockPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DEF11F1CD7BD90006A7C7D /* BlockPointer.cpp */; };
|
||||
49E4F66B1C9CAD16008487EA /* DiagnosticManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49E4F6681C9CAD12008487EA /* DiagnosticManager.cpp */; };
|
||||
4C0083401B9F9BA900D5CF24 /* UtilityFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */; };
|
||||
4C2479BD1BA39295009C9A7B /* FunctionCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083321B9A5DE200D5CF24 /* FunctionCaller.cpp */; };
|
||||
|
@ -1119,6 +1121,7 @@
|
|||
dstPath = "$(DEVELOPER_DIR)/usr/share/man/man1/";
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
49DEF1221CD7BD90006A7C7D /* BlockPointer.h in CopyFiles */,
|
||||
AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
|
@ -2346,6 +2349,8 @@
|
|||
49DCF6FD170E6B4A0092F75E /* IRMemoryMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRMemoryMap.cpp; path = source/Expression/IRMemoryMap.cpp; sourceTree = "<group>"; };
|
||||
49DCF6FF170E6FD90092F75E /* Materializer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Materializer.h; path = include/lldb/Expression/Materializer.h; sourceTree = "<group>"; };
|
||||
49DCF700170E70120092F75E /* Materializer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Materializer.cpp; path = source/Expression/Materializer.cpp; sourceTree = "<group>"; };
|
||||
49DEF11F1CD7BD90006A7C7D /* BlockPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BlockPointer.cpp; path = Language/CPlusPlus/BlockPointer.cpp; sourceTree = "<group>"; };
|
||||
49DEF1201CD7BD90006A7C7D /* BlockPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlockPointer.h; path = Language/CPlusPlus/BlockPointer.h; sourceTree = "<group>"; };
|
||||
49E45FA911F660DC008F7B28 /* CompilerType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompilerType.h; path = include/lldb/Symbol/CompilerType.h; sourceTree = "<group>"; };
|
||||
49E45FAD11F660FE008F7B28 /* CompilerType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompilerType.cpp; path = source/Symbol/CompilerType.cpp; sourceTree = "<group>"; };
|
||||
49E4F6681C9CAD12008487EA /* DiagnosticManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DiagnosticManager.cpp; path = source/Expression/DiagnosticManager.cpp; sourceTree = "<group>"; };
|
||||
|
@ -5586,6 +5591,8 @@
|
|||
945261B01B9A11BE00BF138D /* Formatters */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
49DEF1201CD7BD90006A7C7D /* BlockPointer.h */,
|
||||
49DEF11F1CD7BD90006A7C7D /* BlockPointer.cpp */,
|
||||
945261B41B9A11E800BF138D /* CxxStringTypes.h */,
|
||||
945261B31B9A11E800BF138D /* CxxStringTypes.cpp */,
|
||||
945261B61B9A11E800BF138D /* LibCxx.h */,
|
||||
|
@ -7047,6 +7054,7 @@
|
|||
26E152261419CAD4007967D0 /* ObjectFilePECOFF.cpp in Sources */,
|
||||
B2462247141AD37D00F3D409 /* OptionGroupWatchpoint.cpp in Sources */,
|
||||
94B638631B8FB7F1004FE1E4 /* ObjCPlusPlusLanguage.cpp in Sources */,
|
||||
49DEF1251CD7C6DF006A7C7D /* BlockPointer.cpp in Sources */,
|
||||
49A71FE7141FFA5C00D59478 /* IRInterpreter.cpp in Sources */,
|
||||
49A71FE8141FFACF00D59478 /* DataEncoder.cpp in Sources */,
|
||||
23DDF226196C3EE600BB8417 /* CommandOptionValidators.cpp in Sources */,
|
||||
|
|
|
@ -36,7 +36,6 @@ class BlocksTestCase(TestBase):
|
|||
|
||||
self.wait_for_breakpoint()
|
||||
|
||||
@unittest2.expectedFailure("rdar://problem/10413887 - Call blocks in expressions")
|
||||
@skipUnlessDarwin
|
||||
def test_expr(self):
|
||||
self.launch_common()
|
||||
|
|
|
@ -0,0 +1,225 @@
|
|||
//===-- BlockPointer.cpp ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "BlockPointer.h"
|
||||
|
||||
#include "lldb/Core/ValueObject.h"
|
||||
#include "lldb/DataFormatters/FormattersHelpers.h"
|
||||
#include "lldb/Symbol/ClangASTContext.h"
|
||||
#include "lldb/Symbol/ClangASTImporter.h"
|
||||
#include "lldb/Symbol/CompilerType.h"
|
||||
#include "lldb/Symbol/TypeSystem.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
#include "lldb/Utility/LLDBAssert.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace lldb_private::formatters;
|
||||
|
||||
namespace lldb_private
|
||||
{
|
||||
namespace formatters
|
||||
{
|
||||
|
||||
class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd
|
||||
{
|
||||
public:
|
||||
BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
|
||||
: SyntheticChildrenFrontEnd(*valobj_sp),
|
||||
m_block_struct_type()
|
||||
{
|
||||
CompilerType block_pointer_type(m_backend.GetCompilerType());
|
||||
CompilerType function_pointer_type;
|
||||
block_pointer_type.IsBlockPointerType(&function_pointer_type);
|
||||
|
||||
TargetSP target_sp(m_backend.GetTargetSP());
|
||||
|
||||
if (!target_sp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Error err;
|
||||
TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(&err, lldb::eLanguageTypeC_plus_plus);
|
||||
|
||||
if (!err.Success() || !type_system)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ClangASTContext *clang_ast_context = llvm::dyn_cast<ClangASTContext>(type_system);
|
||||
|
||||
if (!clang_ast_context)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter();
|
||||
|
||||
if (!clang_ast_importer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const char *const isa_name("__isa");
|
||||
const CompilerType isa_type = clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass);
|
||||
const char *const flags_name("__flags");
|
||||
const CompilerType flags_type = clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
|
||||
const char *const reserved_name("__reserved");
|
||||
const CompilerType reserved_type = clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
|
||||
const char *const FuncPtr_name("__FuncPtr");
|
||||
const CompilerType FuncPtr_type = clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type);
|
||||
|
||||
m_block_struct_type = clang_ast_context->CreateStructForIdentifier(ConstString(),
|
||||
{
|
||||
{isa_name, isa_type},
|
||||
{flags_name, flags_type},
|
||||
{reserved_name, reserved_type},
|
||||
{FuncPtr_name, FuncPtr_type}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
~BlockPointerSyntheticFrontEnd() override = default;
|
||||
|
||||
size_t
|
||||
CalculateNumChildren() override
|
||||
{
|
||||
const bool omit_empty_base_classes = false;
|
||||
return m_block_struct_type.GetNumChildren(omit_empty_base_classes);
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP
|
||||
GetChildAtIndex(size_t idx) override
|
||||
{
|
||||
if (!m_block_struct_type.IsValid())
|
||||
{
|
||||
return lldb::ValueObjectSP();
|
||||
}
|
||||
|
||||
if (idx >= CalculateNumChildren())
|
||||
{
|
||||
return lldb::ValueObjectSP();
|
||||
}
|
||||
|
||||
const bool thread_and_frame_only_if_stopped = true;
|
||||
ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
|
||||
const bool transparent_pointers = false;
|
||||
const bool omit_empty_base_classes = false;
|
||||
const bool ignore_array_bounds = false;
|
||||
ValueObject *value_object = nullptr;
|
||||
|
||||
std::string child_name;
|
||||
uint32_t child_byte_size = 0;
|
||||
int32_t child_byte_offset = 0;
|
||||
uint32_t child_bitfield_bit_size = 0;
|
||||
uint32_t child_bitfield_bit_offset = 0;
|
||||
bool child_is_base_class = false;
|
||||
bool child_is_deref_of_parent = false;
|
||||
uint64_t language_flags = 0;
|
||||
|
||||
const CompilerType child_type = m_block_struct_type.GetChildCompilerTypeAtIndex(&exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent, value_object, language_flags);
|
||||
|
||||
ValueObjectSP struct_pointer_sp = m_backend.Cast(m_block_struct_type.GetPointerType());
|
||||
|
||||
if (!struct_pointer_sp)
|
||||
{
|
||||
return lldb::ValueObjectSP();
|
||||
}
|
||||
|
||||
Error err;
|
||||
ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err);
|
||||
|
||||
if (!struct_sp || !err.Success())
|
||||
{
|
||||
return lldb::ValueObjectSP();
|
||||
}
|
||||
|
||||
ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset(child_byte_offset,
|
||||
child_type,
|
||||
true,
|
||||
ConstString(child_name.c_str(), child_name.size())));
|
||||
|
||||
return child_sp;
|
||||
}
|
||||
|
||||
// return true if this object is now safe to use forever without
|
||||
// ever updating again; the typical (and tested) answer here is
|
||||
// 'false'
|
||||
bool
|
||||
Update() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// maybe return false if the block pointer is, say, null
|
||||
bool
|
||||
MightHaveChildren() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
GetIndexOfChildWithName(const ConstString &name) override
|
||||
{
|
||||
if (!m_block_struct_type.IsValid())
|
||||
return UINT32_MAX;
|
||||
|
||||
const bool omit_empty_base_classes = false;
|
||||
return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(), omit_empty_base_classes);
|
||||
}
|
||||
|
||||
private:
|
||||
CompilerType m_block_struct_type;
|
||||
};
|
||||
|
||||
} // namespace formatters
|
||||
} // namespace lldb_private
|
||||
|
||||
bool
|
||||
lldb_private::formatters::BlockPointerSummaryProvider(ValueObject &valobj, Stream &s, const TypeSummaryOptions &)
|
||||
{
|
||||
lldb_private::SyntheticChildrenFrontEnd *synthetic_children = BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP());
|
||||
if (!synthetic_children)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
synthetic_children->Update();
|
||||
|
||||
static const ConstString s_FuncPtr_name("__FuncPtr");
|
||||
|
||||
lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex(synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name));
|
||||
|
||||
if (!child_sp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP qualified_child_representation_sp = child_sp->GetQualifiedRepresentationIfAvailable(lldb::eDynamicDontRunTarget, true);
|
||||
|
||||
const char *child_value = qualified_child_representation_sp->GetValueAsCString();
|
||||
|
||||
s.Printf("%s", child_value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
lldb_private::SyntheticChildrenFrontEnd *
|
||||
lldb_private::formatters::BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp)
|
||||
{
|
||||
if (!valobj_sp)
|
||||
return nullptr;
|
||||
return new BlockPointerSyntheticFrontEnd(valobj_sp);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
//===-- BlockPointer.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_BlockPointer_h_
|
||||
#define liblldb_BlockPointer_h_
|
||||
|
||||
#include "lldb/lldb-forward.h"
|
||||
|
||||
namespace lldb_private
|
||||
{
|
||||
namespace formatters
|
||||
{
|
||||
bool
|
||||
BlockPointerSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &);
|
||||
|
||||
SyntheticChildrenFrontEnd *
|
||||
BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
|
||||
} // namespace formatters
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_BlockPointer_h_
|
|
@ -1,4 +1,5 @@
|
|||
add_lldb_library(lldbPluginCPlusPlusLanguage
|
||||
BlockPointer.cpp
|
||||
CPlusPlusLanguage.cpp
|
||||
CxxStringTypes.cpp
|
||||
LibCxx.cpp
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "lldb/DataFormatters/FormattersHelpers.h"
|
||||
#include "lldb/DataFormatters/VectorType.h"
|
||||
|
||||
#include "BlockPointer.h"
|
||||
#include "CxxStringTypes.h"
|
||||
#include "LibCxx.h"
|
||||
#include "LibCxxAtomic.h"
|
||||
|
@ -769,6 +770,25 @@ CPlusPlusLanguage::GetHardcodedSummaries ()
|
|||
}
|
||||
return nullptr;
|
||||
});
|
||||
g_formatters.push_back(
|
||||
[](lldb_private::ValueObject& valobj,
|
||||
lldb::DynamicValueType,
|
||||
FormatManager& fmt_mgr) -> TypeSummaryImpl::SharedPointer {
|
||||
static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags()
|
||||
.SetCascades(true)
|
||||
.SetDontShowChildren(true)
|
||||
.SetHideItemNames(true)
|
||||
.SetShowMembersOneLiner(true)
|
||||
.SetSkipPointers(true)
|
||||
.SetSkipReferences(false),
|
||||
lldb_private::formatters::BlockPointerSummaryProvider,
|
||||
"block pointer summary provider"));
|
||||
if (valobj.GetCompilerType().IsBlockPointerType(nullptr))
|
||||
{
|
||||
return formatter_sp;
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
});
|
||||
|
||||
return g_formatters;
|
||||
|
@ -796,6 +816,20 @@ CPlusPlusLanguage::GetHardcodedSynthetics ()
|
|||
}
|
||||
return nullptr;
|
||||
});
|
||||
g_formatters.push_back(
|
||||
[](lldb_private::ValueObject& valobj,
|
||||
lldb::DynamicValueType,
|
||||
FormatManager& fmt_mgr) -> SyntheticChildren::SharedPointer {
|
||||
static CXXSyntheticChildren::SharedPointer formatter_sp(new CXXSyntheticChildren(SyntheticChildren::Flags().SetCascades(true).SetSkipPointers(true).SetSkipReferences(true).SetNonCacheable(true),
|
||||
"block pointer synthetic children",
|
||||
lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
|
||||
if (valobj.GetCompilerType().IsBlockPointerType(nullptr))
|
||||
{
|
||||
return formatter_sp;
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return g_formatters;
|
||||
|
|
|
@ -368,6 +368,44 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
|
|||
|
||||
if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
|
||||
{
|
||||
if (tag == DW_TAG_pointer_type)
|
||||
{
|
||||
DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
|
||||
|
||||
if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0))
|
||||
{
|
||||
// Blocks have a __FuncPtr inside them which is a pointer to a function of the proper type.
|
||||
|
||||
for (DWARFDIE child_die = target_die.GetFirstChild();
|
||||
child_die.IsValid();
|
||||
child_die = child_die.GetSibling())
|
||||
{
|
||||
if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""), "__FuncPtr"))
|
||||
{
|
||||
DWARFDIE function_pointer_type = child_die.GetReferencedDIE(DW_AT_type);
|
||||
|
||||
if (function_pointer_type)
|
||||
{
|
||||
DWARFDIE function_type = function_pointer_type.GetReferencedDIE(DW_AT_type);
|
||||
|
||||
bool function_type_is_new_pointer;
|
||||
TypeSP lldb_function_type_sp = ParseTypeFromDWARF(sc, function_type, log, &function_type_is_new_pointer);
|
||||
|
||||
if (lldb_function_type_sp)
|
||||
{
|
||||
clang_type = m_ast.CreateBlockPointerType(lldb_function_type_sp->GetForwardCompilerType());
|
||||
encoding_data_type = Type::eEncodingIsUID;
|
||||
encoding_uid.Clear();
|
||||
resolve_state = Type::eResolveStateFull;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
|
||||
|
||||
if (translation_unit_is_objc)
|
||||
|
|
|
@ -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 @@ ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl
|
|||
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 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type,
|
|||
}
|
||||
|
||||
CompilerType
|
||||
ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
|
||||
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 @@ ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
|
|||
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
|
||||
|
@ -3176,6 +3202,52 @@ ClangASTContext::IsFunctionPointerType (lldb::opaque_compiler_type_t type)
|
|||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -177,7 +177,14 @@ CompilerType::IsFunctionPointerType () const
|
|||
if (IsValid())
|
||||
return m_type_system->IsFunctionPointerType(m_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CompilerType::IsBlockPointerType (CompilerType *function_pointer_type_ptr) const
|
||||
{
|
||||
if (IsValid())
|
||||
return m_type_system->IsBlockPointerType(m_type, function_pointer_type_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -537,6 +537,12 @@ GoASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type)
|
|||
return IsFunctionType(type);
|
||||
}
|
||||
|
||||
bool
|
||||
GoASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
GoASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed)
|
||||
{
|
||||
|
|
|
@ -628,6 +628,12 @@ JavaASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
JavaASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
JavaASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue