Changeset View
Changeset View
Standalone View
Standalone View
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Show First 20 Lines • Show All 280 Lines • ▼ Show 20 Lines | die.GetDWARF()->GetObjectFile()->GetModule()->ReportError( | ||||
type_name_cstr ? type_name_cstr : "", die.GetOffset()); | type_name_cstr ? type_name_cstr : "", die.GetOffset()); | ||||
} | } | ||||
// We don't have a type definition and/or the import failed. We must | // We don't have a type definition and/or the import failed. We must | ||||
// forcefully complete the type to avoid crashes. | // forcefully complete the type to avoid crashes. | ||||
ForcefullyCompleteType(type); | ForcefullyCompleteType(type); | ||||
} | } | ||||
ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) { | |||||
DWARFAttributes attributes; | |||||
size_t num_attributes = die.GetAttributes(attributes); | |||||
for (size_t i = 0; i < num_attributes; ++i) { | |||||
dw_attr_t attr = attributes.AttributeAtIndex(i); | |||||
DWARFFormValue form_value; | |||||
if (!attributes.ExtractFormValueAtIndex(i, form_value)) | |||||
continue; | |||||
switch (attr) { | |||||
case DW_AT_abstract_origin: | |||||
abstract_origin = form_value; | |||||
break; | |||||
case DW_AT_accessibility: | |||||
accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); | |||||
break; | |||||
case DW_AT_artificial: | |||||
is_artificial = form_value.Boolean(); | |||||
break; | |||||
case DW_AT_bit_stride: | |||||
bit_stride = form_value.Unsigned(); | |||||
break; | |||||
case DW_AT_byte_size: | |||||
byte_size = form_value.Unsigned(); | |||||
break; | |||||
case DW_AT_byte_stride: | |||||
byte_stride = form_value.Unsigned(); | |||||
break; | |||||
case DW_AT_calling_convention: | |||||
calling_convention = form_value.Unsigned(); | |||||
break; | |||||
case DW_AT_containing_type: | |||||
containing_type = form_value; | |||||
break; | |||||
case DW_AT_decl_file: | |||||
// die.GetCU() can differ if DW_AT_specification uses DW_FORM_ref_addr. | |||||
decl.SetFile( | |||||
attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned())); | |||||
break; | |||||
case DW_AT_decl_line: | |||||
decl.SetLine(form_value.Unsigned()); | |||||
break; | |||||
case DW_AT_decl_column: | |||||
decl.SetColumn(form_value.Unsigned()); | |||||
break; | |||||
case DW_AT_declaration: | |||||
is_forward_declaration = form_value.Boolean(); | |||||
break; | |||||
case DW_AT_encoding: | |||||
encoding = form_value.Unsigned(); | |||||
break; | |||||
case DW_AT_enum_class: | |||||
is_scoped_enum = form_value.Boolean(); | |||||
break; | |||||
case DW_AT_explicit: | |||||
is_explicit = form_value.Boolean(); | |||||
break; | |||||
case DW_AT_external: | |||||
if (form_value.Unsigned()) | |||||
storage = clang::SC_Extern; | |||||
break; | |||||
case DW_AT_inline: | |||||
is_inline = form_value.Boolean(); | |||||
break; | |||||
case DW_AT_linkage_name: | |||||
case DW_AT_MIPS_linkage_name: | |||||
mangled_name = form_value.AsCString(); | |||||
break; | |||||
case DW_AT_name: | |||||
name.SetCString(form_value.AsCString()); | |||||
break; | |||||
case DW_AT_object_pointer: | |||||
object_pointer = form_value.Reference(); | |||||
break; | |||||
case DW_AT_signature: | |||||
signature = form_value; | |||||
break; | |||||
case DW_AT_specification: | |||||
specification = form_value; | |||||
break; | |||||
case DW_AT_type: | |||||
type = form_value; | |||||
break; | |||||
case DW_AT_virtuality: | |||||
is_virtual = form_value.Boolean(); | |||||
break; | |||||
case DW_AT_APPLE_objc_complete_type: | |||||
is_complete_objc_class = form_value.Signed(); | |||||
break; | |||||
case DW_AT_APPLE_objc_direct: | |||||
is_objc_direct_call = true; | |||||
break; | |||||
case DW_AT_APPLE_runtime_class: | |||||
class_language = (LanguageType)form_value.Signed(); | |||||
break; | |||||
case DW_AT_GNU_vector: | |||||
is_vector = form_value.Boolean(); | |||||
break; | |||||
case DW_AT_export_symbols: | |||||
exports_symbols = form_value.Boolean(); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
static std::string GetUnitName(const DWARFDIE &die) { | static std::string GetUnitName(const DWARFDIE &die) { | ||||
if (DWARFUnit *unit = die.GetCU()) | if (DWARFUnit *unit = die.GetCU()) | ||||
return unit->GetAbsolutePath().GetPath(); | return unit->GetAbsolutePath().GetPath(); | ||||
return "<missing DWARF unit path>"; | return "<missing DWARF unit path>"; | ||||
} | } | ||||
TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, | TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, | ||||
const DWARFDIE &die, | const DWARFDIE &die, | ||||
▲ Show 20 Lines • Show All 333 Lines • ▼ Show 20 Lines | TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, | ||||
const DWARFDIE &die, | const DWARFDIE &die, | ||||
ParsedDWARFTypeAttributes &attrs) { | ParsedDWARFTypeAttributes &attrs) { | ||||
Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | | Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | | ||||
DWARF_LOG_LOOKUPS)); | DWARF_LOG_LOOKUPS)); | ||||
SymbolFileDWARF *dwarf = die.GetDWARF(); | SymbolFileDWARF *dwarf = die.GetDWARF(); | ||||
const dw_tag_t tag = die.Tag(); | const dw_tag_t tag = die.Tag(); | ||||
TypeSP type_sp; | TypeSP type_sp; | ||||
if (attrs.is_forward_declaration) { | if (attrs.isForwardDeclaration()) { | ||||
type_sp = ParseTypeFromClangModule(sc, die, log); | type_sp = ParseTypeFromClangModule(sc, die, log); | ||||
if (type_sp) | if (type_sp) | ||||
return type_sp; | return type_sp; | ||||
DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); | DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); | ||||
type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); | type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | if (!enumerator_clang_type) { | ||||
enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt); | enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt); | ||||
} | } | ||||
} | } | ||||
clang_type = m_ast.CreateEnumerationType( | clang_type = m_ast.CreateEnumerationType( | ||||
attrs.name.GetStringRef(), | attrs.name.GetStringRef(), | ||||
GetClangDeclContextContainingDIE(die, nullptr), | GetClangDeclContextContainingDIE(die, nullptr), | ||||
GetOwningClangModule(die), attrs.decl, enumerator_clang_type, | GetOwningClangModule(die), attrs.decl, enumerator_clang_type, | ||||
attrs.is_scoped_enum); | attrs.isScopedEnum()); | ||||
} else { | } else { | ||||
enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type); | enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type); | ||||
} | } | ||||
LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die); | LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die); | ||||
type_sp = std::make_shared<Type>( | type_sp = std::make_shared<Type>( | ||||
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, | die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, | ||||
▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) { | ||||
// If accessibility isn't set to anything valid, assume public | // If accessibility isn't set to anything valid, assume public | ||||
// for now... | // for now... | ||||
if (attrs.accessibility == eAccessNone) | if (attrs.accessibility == eAccessNone) | ||||
attrs.accessibility = eAccessPublic; | attrs.accessibility = eAccessPublic; | ||||
clang::ObjCMethodDecl *objc_method_decl = | clang::ObjCMethodDecl *objc_method_decl = | ||||
m_ast.AddMethodToObjCObjectType( | m_ast.AddMethodToObjCObjectType( | ||||
class_opaque_type, attrs.name.GetCString(), clang_type, | class_opaque_type, attrs.name.GetCString(), clang_type, | ||||
attrs.accessibility, attrs.is_artificial, is_variadic, | attrs.accessibility, attrs.isArtificial(), is_variadic, | ||||
attrs.is_objc_direct_call); | attrs.isObjCDirectCall()); | ||||
type_handled = objc_method_decl != NULL; | type_handled = objc_method_decl != NULL; | ||||
if (type_handled) { | if (type_handled) { | ||||
LinkDeclContextToDIE(objc_method_decl, die); | LinkDeclContextToDIE(objc_method_decl, die); | ||||
m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); | m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); | ||||
} else { | } else { | ||||
dwarf->GetObjectFile()->GetModule()->ReportError( | dwarf->GetObjectFile()->GetModule()->ReportError( | ||||
"{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), " | "{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), " | ||||
"please file a bug and attach the file at the start of " | "please file a bug and attach the file at the start of " | ||||
▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) { | ||||
// Default to public for now... | // Default to public for now... | ||||
if (attrs.accessibility == eAccessNone) | if (attrs.accessibility == eAccessNone) | ||||
attrs.accessibility = eAccessPublic; | attrs.accessibility = eAccessPublic; | ||||
clang::CXXMethodDecl *cxx_method_decl = | clang::CXXMethodDecl *cxx_method_decl = | ||||
m_ast.AddMethodToCXXRecordType( | m_ast.AddMethodToCXXRecordType( | ||||
class_opaque_type.GetOpaqueQualType(), | class_opaque_type.GetOpaqueQualType(), | ||||
attrs.name.GetCString(), attrs.mangled_name, | attrs.name.GetCString(), attrs.mangled_name, | ||||
clang_type, attrs.accessibility, attrs.is_virtual, | clang_type, attrs.accessibility, attrs.isVirtual(), | ||||
is_static, attrs.is_inline, attrs.is_explicit, | is_static, attrs.isInline(), attrs.isExplicit(), | ||||
is_attr_used, attrs.is_artificial); | is_attr_used, attrs.isArtificial()); | ||||
type_handled = cxx_method_decl != NULL; | type_handled = cxx_method_decl != NULL; | ||||
// Artificial methods are always handled even when we | // Artificial methods are always handled even when we | ||||
// don't create a new declaration for them. | // don't create a new declaration for them. | ||||
type_handled |= attrs.is_artificial; | type_handled |= attrs.isArtificial(); | ||||
if (cxx_method_decl) { | if (cxx_method_decl) { | ||||
LinkDeclContextToDIE(cxx_method_decl, die); | LinkDeclContextToDIE(cxx_method_decl, die); | ||||
ClangASTMetadata metadata; | ClangASTMetadata metadata; | ||||
metadata.SetUserID(die.GetID()); | metadata.SetUserID(die.GetID()); | ||||
if (!object_pointer_name.empty()) { | if (!object_pointer_name.empty()) { | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | if (!type_handled) { | ||||
name = name_buf; | name = name_buf; | ||||
} | } | ||||
} | } | ||||
// We just have a function that isn't part of a class | // We just have a function that isn't part of a class | ||||
function_decl = m_ast.CreateFunctionDeclaration( | function_decl = m_ast.CreateFunctionDeclaration( | ||||
ignore_containing_context ? m_ast.GetTranslationUnitDecl() | ignore_containing_context ? m_ast.GetTranslationUnitDecl() | ||||
: containing_decl_ctx, | : containing_decl_ctx, | ||||
GetOwningClangModule(die), name, clang_type, attrs.storage, | GetOwningClangModule(die), name, clang_type, attrs.isExternal() ? clang::SC_Extern : clang::SC_None, | ||||
attrs.is_inline); | attrs.isInline()); | ||||
shafik: Is there a reason not to use an attribute `storage` like before? This feels like we are leaking… | |||||
I think the abstraction of the external attribute is valid since storage is Clang specific StorageClass. ljmf00: I think the abstraction of the external attribute is valid since `storage` is Clang specific… | |||||
std::free(name_buf); | std::free(name_buf); | ||||
if (has_template_params) { | if (has_template_params) { | ||||
TypeSystemClang::TemplateParameterInfos template_param_infos; | TypeSystemClang::TemplateParameterInfos template_param_infos; | ||||
ParseTemplateParameterInfos(die, template_param_infos); | ParseTemplateParameterInfos(die, template_param_infos); | ||||
template_function_decl = m_ast.CreateFunctionDeclaration( | template_function_decl = m_ast.CreateFunctionDeclaration( | ||||
ignore_containing_context ? m_ast.GetTranslationUnitDecl() | ignore_containing_context ? m_ast.GetTranslationUnitDecl() | ||||
: containing_decl_ctx, | : containing_decl_ctx, | ||||
GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type, | GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type, | ||||
attrs.storage, attrs.is_inline); | attrs.isExternal() ? clang::SC_Extern : clang::SC_None, attrs.isInline()); | ||||
clang::FunctionTemplateDecl *func_template_decl = | clang::FunctionTemplateDecl *func_template_decl = | ||||
m_ast.CreateFunctionTemplateDecl( | m_ast.CreateFunctionTemplateDecl( | ||||
containing_decl_ctx, GetOwningClangModule(die), | containing_decl_ctx, GetOwningClangModule(die), | ||||
template_function_decl, template_param_infos); | template_function_decl, template_param_infos); | ||||
m_ast.CreateFunctionTemplateSpecializationInfo( | m_ast.CreateFunctionTemplateSpecializationInfo( | ||||
template_function_decl, func_template_decl, template_param_infos); | template_function_decl, func_template_decl, template_param_infos); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | uint64_t array_element_bit_stride = | ||||
attrs.byte_stride * 8 + attrs.bit_stride; | attrs.byte_stride * 8 + attrs.bit_stride; | ||||
CompilerType clang_type; | CompilerType clang_type; | ||||
if (array_info && array_info->element_orders.size() > 0) { | if (array_info && array_info->element_orders.size() > 0) { | ||||
uint64_t num_elements = 0; | uint64_t num_elements = 0; | ||||
auto end = array_info->element_orders.rend(); | auto end = array_info->element_orders.rend(); | ||||
for (auto pos = array_info->element_orders.rbegin(); pos != end; ++pos) { | for (auto pos = array_info->element_orders.rbegin(); pos != end; ++pos) { | ||||
num_elements = *pos; | num_elements = *pos; | ||||
clang_type = m_ast.CreateArrayType(array_element_type, num_elements, | clang_type = m_ast.CreateArrayType(array_element_type, num_elements, | ||||
attrs.is_vector); | attrs.isVector()); | ||||
array_element_type = clang_type; | array_element_type = clang_type; | ||||
array_element_bit_stride = num_elements | array_element_bit_stride = num_elements | ||||
? array_element_bit_stride * num_elements | ? array_element_bit_stride * num_elements | ||||
: array_element_bit_stride; | : array_element_bit_stride; | ||||
} | } | ||||
} else { | } else { | ||||
clang_type = | clang_type = | ||||
m_ast.CreateArrayType(array_element_type, 0, attrs.is_vector); | m_ast.CreateArrayType(array_element_type, 0, attrs.isVector()); | ||||
} | } | ||||
ConstString empty_name; | ConstString empty_name; | ||||
TypeSP type_sp = std::make_shared<Type>( | TypeSP type_sp = std::make_shared<Type>( | ||||
die.GetID(), dwarf, empty_name, array_element_bit_stride / 8, nullptr, | die.GetID(), dwarf, empty_name, array_element_bit_stride / 8, nullptr, | ||||
dwarf->GetUID(type_die), Type::eEncodingIsUID, &attrs.decl, clang_type, | dwarf->GetUID(type_die), Type::eEncodingIsUID, &attrs.decl, clang_type, | ||||
Type::ResolveState::Full); | Type::ResolveState::Full); | ||||
type_sp->SetEncodingType(element_type); | type_sp->SetEncodingType(element_type); | ||||
const clang::Type *type = ClangUtil::GetQualType(clang_type).getTypePtr(); | const clang::Type *type = ClangUtil::GetQualType(clang_type).getTypePtr(); | ||||
▲ Show 20 Lines • Show All 243 Lines • ▼ Show 20 Lines | if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name && | ||||
// DW_TAG_structure_type [2] | // DW_TAG_structure_type [2] | ||||
// DW_AT_name( "ForwardObjcClass" ) | // DW_AT_name( "ForwardObjcClass" ) | ||||
// DW_AT_byte_size( 0x00 ) | // DW_AT_byte_size( 0x00 ) | ||||
// DW_AT_decl_file( "..." ) | // DW_AT_decl_file( "..." ) | ||||
// DW_AT_decl_line( 1 ) | // DW_AT_decl_line( 1 ) | ||||
// | // | ||||
// Note that there is no DW_AT_declaration and there are no children, | // Note that there is no DW_AT_declaration and there are no children, | ||||
// and the byte size is zero. | // and the byte size is zero. | ||||
attrs.is_forward_declaration = true; | attrs.setIsForwardDeclaration(); | ||||
Not Done ReplyInline Actionsif we are going to have getter abstraction why not have a setIsForwardDeclaration() or something similar. shafik: if we are going to have getter abstraction why not have a `setIsForwardDeclaration()` or… | |||||
Yeah, I can see the improvement, I added setters too. I didn't add them since the set was only used as a statement rather than an expression. ljmf00: Yeah, I can see the improvement, I added setters too. I didn't add them since the set was only… | |||||
} | } | ||||
if (attrs.class_language == eLanguageTypeObjC || | if (attrs.class_language == eLanguageTypeObjC || | ||||
attrs.class_language == eLanguageTypeObjC_plus_plus) { | attrs.class_language == eLanguageTypeObjC_plus_plus) { | ||||
if (!attrs.is_complete_objc_class && | if (!attrs.isObjCCompleteType() && | ||||
die.Supports_DW_AT_APPLE_objc_complete_type()) { | die.Supports_DW_AT_APPLE_objc_complete_type()) { | ||||
// We have a valid eSymbolTypeObjCClass class symbol whose name | // We have a valid eSymbolTypeObjCClass class symbol whose name | ||||
// matches the current objective C class that we are trying to find | // matches the current objective C class that we are trying to find | ||||
// and this DIE isn't the complete definition (we checked | // and this DIE isn't the complete definition (we checked | ||||
// is_complete_objc_class above and know it is false), so the real | // is_complete_objc_class above and know it is false), so the real | ||||
// definition is in here somewhere | // definition is in here somewhere | ||||
type_sp = | type_sp = | ||||
dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true); | dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true); | ||||
Show All 24 Lines | if (!attrs.isObjCCompleteType() && | ||||
// it and cache the fact that we found a complete type for this | // it and cache the fact that we found a complete type for this | ||||
// die | // die | ||||
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); | dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); | ||||
return type_sp; | return type_sp; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (attrs.is_forward_declaration) { | if (attrs.isForwardDeclaration()) { | ||||
// We have a forward declaration to a type and we need to try and | // We have a forward declaration to a type and we need to try and | ||||
// find a full declaration. We look in the current type index just in | // find a full declaration. We look in the current type index just in | ||||
// case we have a forward declaration followed by an actual | // case we have a forward declaration followed by an actual | ||||
// declarations in the DWARF. If this fails, we need to look | // declarations in the DWARF. If this fails, we need to look | ||||
// elsewhere... | // elsewhere... | ||||
if (log) { | if (log) { | ||||
dwarf->GetObjectFile()->GetModule()->LogMessage( | dwarf->GetObjectFile()->GetModule()->LogMessage( | ||||
log, | log, | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | if (attrs.name.GetStringRef().contains('<')) { | ||||
} | } | ||||
} | } | ||||
if (!clang_type_was_created) { | if (!clang_type_was_created) { | ||||
clang_type_was_created = true; | clang_type_was_created = true; | ||||
clang_type = m_ast.CreateRecordType( | clang_type = m_ast.CreateRecordType( | ||||
decl_ctx, GetOwningClangModule(die), attrs.accessibility, | decl_ctx, GetOwningClangModule(die), attrs.accessibility, | ||||
attrs.name.GetCString(), tag_decl_kind, attrs.class_language, | attrs.name.GetCString(), tag_decl_kind, attrs.class_language, | ||||
&metadata, attrs.exports_symbols); | &metadata, attrs.isExportsSymbols()); | ||||
} | } | ||||
} | } | ||||
// Store a forward declaration to this class type in case any | // Store a forward declaration to this class type in case any | ||||
// parameters in any class methods need it for the clang types for | // parameters in any class methods need it for the clang types for | ||||
// function prototypes. | // function prototypes. | ||||
LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); | LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); | ||||
type_sp = std::make_shared<Type>( | type_sp = std::make_shared<Type>( | ||||
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, | die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, | ||||
LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, clang_type, | LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, clang_type, | ||||
Type::ResolveState::Forward, | Type::ResolveState::Forward, | ||||
TypePayloadClang(OptionalClangModuleID(), attrs.is_complete_objc_class)); | TypePayloadClang(OptionalClangModuleID(), attrs.isObjCCompleteType())); | ||||
// Add our type to the unique type map so we don't end up creating many | // Add our type to the unique type map so we don't end up creating many | ||||
// copies of the same type over and over in the ASTContext for our | // copies of the same type over and over in the ASTContext for our | ||||
// module | // module | ||||
unique_ast_entry_up->m_type_sp = type_sp; | unique_ast_entry_up->m_type_sp = type_sp; | ||||
unique_ast_entry_up->m_die = die; | unique_ast_entry_up->m_die = die; | ||||
unique_ast_entry_up->m_declaration = unique_decl; | unique_ast_entry_up->m_declaration = unique_decl; | ||||
unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0); | unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0); | ||||
dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename, | dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename, | ||||
*unique_ast_entry_up); | *unique_ast_entry_up); | ||||
if (!attrs.is_forward_declaration) { | if (!attrs.isForwardDeclaration()) { | ||||
// Always start the definition for a class type so that if the class | // Always start the definition for a class type so that if the class | ||||
// has child classes or types that require the class to be created | // has child classes or types that require the class to be created | ||||
// for use as their decl contexts the class will be ready to accept | // for use as their decl contexts the class will be ready to accept | ||||
// these child definitions. | // these child definitions. | ||||
if (!die.HasChildren()) { | if (!die.HasChildren()) { | ||||
// No children for this struct/union/class, lets finish it | // No children for this struct/union/class, lets finish it | ||||
if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { | if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { | ||||
TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); | TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); | ||||
▲ Show 20 Lines • Show All 1,877 Lines • Show Last 20 Lines |
Is there a reason not to use an attribute storage like before? This feels like we are leaking out of the abstraction where before we were not.