forked from OSchip/llvm-project
<rdar://problem/13119621>
Make dynamic type detection faster by using the AST metadata to help out and allow us not to complete types when we don't need to. After running "purge" on a MacOSX system, the Xcode variables view now populates more than 3x faster with this fix. llvm-svn: 176676
This commit is contained in:
parent
fd7d67e18f
commit
c4ffd66f06
|
@ -50,10 +50,23 @@ public:
|
|||
m_union_is_user_id(false),
|
||||
m_union_is_isa_ptr(false),
|
||||
m_has_object_ptr(false),
|
||||
m_is_self (false)
|
||||
m_is_self (false),
|
||||
m_is_dynamic_cxx (true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GetIsDynamicCXXType () const
|
||||
{
|
||||
return m_is_dynamic_cxx;
|
||||
}
|
||||
|
||||
void
|
||||
SetIsDynamicCXXType (bool b)
|
||||
{
|
||||
m_is_dynamic_cxx = b;
|
||||
}
|
||||
|
||||
void
|
||||
SetUserID (lldb::user_id_t user_id)
|
||||
{
|
||||
|
@ -136,7 +149,8 @@ private:
|
|||
bool m_union_is_user_id : 1,
|
||||
m_union_is_isa_ptr : 1,
|
||||
m_has_object_ptr : 1,
|
||||
m_is_self : 1;
|
||||
m_is_self : 1,
|
||||
m_is_dynamic_cxx : 1;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1372,7 +1372,7 @@ public:
|
|||
const char *property_setter_name,
|
||||
const char *property_getter_name,
|
||||
uint32_t property_attributes,
|
||||
const ClangASTMetadata *metadata
|
||||
const ClangASTMetadata *metadata
|
||||
) :
|
||||
m_ast (ast),
|
||||
m_class_opaque_type (class_opaque_type),
|
||||
|
@ -1386,7 +1386,7 @@ public:
|
|||
if (metadata != NULL)
|
||||
{
|
||||
m_metadata_ap.reset(new ClangASTMetadata());
|
||||
*(m_metadata_ap.get()) = *metadata;
|
||||
*m_metadata_ap = *metadata;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1409,22 +1409,22 @@ public:
|
|||
if (rhs.m_metadata_ap.get())
|
||||
{
|
||||
m_metadata_ap.reset (new ClangASTMetadata());
|
||||
*(m_metadata_ap.get()) = *(rhs.m_metadata_ap.get());
|
||||
*m_metadata_ap = *rhs.m_metadata_ap;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Finalize() const
|
||||
{
|
||||
return ClangASTContext::AddObjCClassProperty(m_ast,
|
||||
m_class_opaque_type,
|
||||
m_property_name,
|
||||
m_property_opaque_type,
|
||||
m_ivar_decl,
|
||||
m_property_setter_name,
|
||||
m_property_getter_name,
|
||||
m_property_attributes,
|
||||
m_metadata_ap.get());
|
||||
return ClangASTContext::AddObjCClassProperty (m_ast,
|
||||
m_class_opaque_type,
|
||||
m_property_name,
|
||||
m_property_opaque_type,
|
||||
m_ivar_decl,
|
||||
m_property_setter_name,
|
||||
m_property_getter_name,
|
||||
m_property_attributes,
|
||||
m_metadata_ap.get());
|
||||
}
|
||||
private:
|
||||
clang::ASTContext *m_ast;
|
||||
|
@ -1435,7 +1435,7 @@ private:
|
|||
const char *m_property_setter_name;
|
||||
const char *m_property_getter_name;
|
||||
uint32_t m_property_attributes;
|
||||
std::auto_ptr<ClangASTMetadata> m_metadata_ap;
|
||||
std::auto_ptr<ClangASTMetadata> m_metadata_ap;
|
||||
};
|
||||
|
||||
struct BitfieldInfo
|
||||
|
@ -1456,6 +1456,36 @@ struct BitfieldInfo
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
SymbolFileDWARF::ClassOrStructIsVirtual (DWARFCompileUnit* dwarf_cu,
|
||||
const DWARFDebugInfoEntry *parent_die)
|
||||
{
|
||||
if (parent_die)
|
||||
{
|
||||
for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
|
||||
{
|
||||
dw_tag_t tag = die->Tag();
|
||||
bool check_virtuality = false;
|
||||
switch (tag)
|
||||
{
|
||||
case DW_TAG_inheritance:
|
||||
case DW_TAG_subprogram:
|
||||
check_virtuality = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (check_virtuality)
|
||||
{
|
||||
if (die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_virtuality, 0) != 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t
|
||||
SymbolFileDWARF::ParseChildMembers
|
||||
(
|
||||
|
@ -5868,6 +5898,10 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
|
|||
accessibility = default_accessibility;
|
||||
}
|
||||
|
||||
ClangASTMetadata metadata;
|
||||
metadata.SetUserID(MakeUserID(die->GetOffset()));
|
||||
metadata.SetIsDynamicCXXType(ClassOrStructIsVirtual (dwarf_cu, die));
|
||||
|
||||
if (type_name_cstr && strchr (type_name_cstr, '<'))
|
||||
{
|
||||
ClangASTContext::TemplateParameterInfos template_param_infos;
|
||||
|
@ -5886,16 +5920,14 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
|
|||
clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
|
||||
clang_type_was_created = true;
|
||||
|
||||
GetClangASTContext().SetMetadataAsUserID ((uintptr_t)class_template_decl, MakeUserID(die->GetOffset()));
|
||||
GetClangASTContext().SetMetadataAsUserID ((uintptr_t)class_specialization_decl, MakeUserID(die->GetOffset()));
|
||||
GetClangASTContext().SetMetadata ((uintptr_t)class_template_decl, metadata);
|
||||
GetClangASTContext().SetMetadata ((uintptr_t)class_specialization_decl, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
if (!clang_type_was_created)
|
||||
{
|
||||
clang_type_was_created = true;
|
||||
ClangASTMetadata metadata;
|
||||
metadata.SetUserID(MakeUserID(die->GetOffset()));
|
||||
clang_type = ast.CreateRecordType (decl_ctx,
|
||||
accessibility,
|
||||
type_name_cstr,
|
||||
|
|
|
@ -338,6 +338,10 @@ protected:
|
|||
class DelayedAddObjCClassProperty;
|
||||
typedef std::vector <DelayedAddObjCClassProperty> DelayedPropertyList;
|
||||
|
||||
bool ClassOrStructIsVirtual (
|
||||
DWARFCompileUnit* dwarf_cu,
|
||||
const DWARFDebugInfoEntry *parent_die);
|
||||
|
||||
size_t ParseChildMembers(
|
||||
const lldb_private::SymbolContext& sc,
|
||||
DWARFCompileUnit* dwarf_cu,
|
||||
|
|
|
@ -1126,7 +1126,12 @@ ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
|
|||
#pragma mark Structure, Unions, Classes
|
||||
|
||||
clang_type_t
|
||||
ClangASTContext::CreateRecordType (DeclContext *decl_ctx, AccessType access_type, const char *name, int kind, LanguageType language, ClangASTMetadata *metadata)
|
||||
ClangASTContext::CreateRecordType (DeclContext *decl_ctx,
|
||||
AccessType access_type,
|
||||
const char *name,
|
||||
int kind,
|
||||
LanguageType language,
|
||||
ClangASTMetadata *metadata)
|
||||
{
|
||||
ASTContext *ast = getASTContext();
|
||||
assert (ast != NULL);
|
||||
|
@ -1154,16 +1159,20 @@ ClangASTContext::CreateRecordType (DeclContext *decl_ctx, AccessType access_type
|
|||
SourceLocation(),
|
||||
name && name[0] ? &ast->Idents.get(name) : NULL);
|
||||
|
||||
if (decl && metadata)
|
||||
SetMetadata(ast, (uintptr_t)decl, *metadata);
|
||||
|
||||
if (decl_ctx)
|
||||
if (decl)
|
||||
{
|
||||
if (metadata)
|
||||
SetMetadata(ast, (uintptr_t)decl, *metadata);
|
||||
|
||||
if (access_type != eAccessNone)
|
||||
decl->setAccess (ConvertAccessTypeToAccessSpecifier (access_type));
|
||||
decl_ctx->addDecl (decl);
|
||||
|
||||
if (decl_ctx)
|
||||
decl_ctx->addDecl (decl);
|
||||
|
||||
return ast->getTagDeclType(decl).getAsOpaquePtr();
|
||||
}
|
||||
return ast->getTagDeclType(decl).getAsOpaquePtr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static TemplateParameterList *
|
||||
|
@ -5732,16 +5741,22 @@ ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast,
|
|||
if (cxx_record_decl)
|
||||
{
|
||||
bool is_complete = cxx_record_decl->isCompleteDefinition();
|
||||
if (!is_complete)
|
||||
is_complete = ClangASTContext::GetCompleteType (ast, pointee_qual_type.getAsOpaquePtr());
|
||||
|
||||
|
||||
if (is_complete)
|
||||
{
|
||||
success = cxx_record_decl->isDynamicClass();
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
ClangASTMetadata *metadata = GetMetadata (ast, (uintptr_t)cxx_record_decl);
|
||||
if (metadata)
|
||||
success = metadata->GetIsDynamicCXXType();
|
||||
else
|
||||
{
|
||||
is_complete = ClangASTContext::GetCompleteType (ast, pointee_qual_type.getAsOpaquePtr());
|
||||
if (is_complete)
|
||||
success = cxx_record_decl->isDynamicClass();
|
||||
else
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
|
|
Loading…
Reference in New Issue