From 0fffff581665b768d100eece196e59b00eb16e7e Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Fri, 24 Sep 2010 05:15:53 +0000 Subject: [PATCH] Added the ability to create an objective C method for an objective C interface in ClangASTContext. Also added two bool returning functions that indicated if an opaque clang qual type is a CXX class type, and if it is an ObjC class type. Objective C classes now will get their methods added lazily as they are encountered. The reason for this is currently, unlike C++, the DW_TAG_structure_type and owns the ivars, doesn't not also contain the member functions. This means when we parse the objective C class interface we either need to find all functions whose names start with "+[CLASS_NAME" or "-[CLASS_NAME" and add them all to the class, or when we parse each objective C function, we slowly add it to the class interface definition. Since objective C's class doesn't change internal bits according to whether it has certain types of member functions (like C++ does if it has virtual functions, or if it has user ctors/dtors), I currently chose to lazily populate the class when each functions is parsed. Another issue we run into with ObjC method declarations is the "self" and "_cmd" implicit args are not marked as artificial in the DWARF (DW_AT_artifical), so we currently have to look for the parameters by name if we are trying to omit artificial function args if the language of the compile unit is ObjC or ObjC++. llvm-svn: 114722 --- lldb/include/lldb/Symbol/ClangASTContext.h | 63 +++- lldb/lldb.xcodeproj/project.pbxproj | 1 + .../Expression/ClangExpressionDeclMap.cpp | 18 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 297 ++++++++---------- .../SymbolFile/DWARF/SymbolFileDWARF.h | 24 +- lldb/source/Symbol/ClangASTContext.cpp | 230 +++++++++++--- 6 files changed, 399 insertions(+), 234 deletions(-) diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index ed41f166ca86..073b3329210a 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -174,12 +174,12 @@ public: lldb::AccessType access, uint32_t bitfield_bit_size) { - return ClangASTContext::AddFieldToRecordType(getASTContext(), - record_qual_type, - name, - field_type, - access, - bitfield_bit_size); + return ClangASTContext::AddFieldToRecordType (getASTContext(), + record_qual_type, + name, + field_type, + access, + bitfield_bit_size); } static clang::CXXMethodDecl * @@ -188,22 +188,28 @@ public: const char *name, void *method_type, lldb::AccessType access, - bool is_virtual); + bool is_virtual, + bool is_static, + bool is_inline); clang::CXXMethodDecl * AddMethodToCXXRecordType (void *record_opaque_type, const char *name, void *method_type, lldb::AccessType access, - bool is_virtual) + bool is_virtual, + bool is_static, + bool is_inline) { - return ClangASTContext::AddMethodToCXXRecordType(getASTContext(), - record_opaque_type, - name, - method_type, - access, - is_virtual); + return ClangASTContext::AddMethodToCXXRecordType (getASTContext(), + record_opaque_type, + name, + method_type, + access, + is_virtual, + is_static, + is_inline); } bool @@ -267,7 +273,28 @@ public: ObjCDeclHasIVars (clang::ObjCInterfaceDecl *class_interface_decl, bool check_superclass); - + + static clang::ObjCMethodDecl * + AddMethodToObjCObjectType (clang::ASTContext *ast_context, + void *class_opaque_type, + const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") + void *method_opaque_type, + lldb::AccessType access); + + clang::ObjCMethodDecl * + AddMethodToObjCObjectType (void *class_opaque_type, + const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") + void *method_opaque_type, + lldb::AccessType access) + { + return AddMethodToObjCObjectType (getASTContext(), + class_opaque_type, + name, + method_opaque_type, + access); + } + + //------------------------------------------------------------------ // Aggregate Types //------------------------------------------------------------------ @@ -495,6 +522,12 @@ public: static bool IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex); + static bool + IsCXXClassType (void *clang_type); + + static bool + IsObjCClassType (void *clang_type); + //static bool //ConvertFloatValueToString (clang::ASTContext *ast_context, // void *clang_type, diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 249f896626da..b32c17dba992 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -2432,6 +2432,7 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 189249f56801..93d7ad5bc3cb 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -1206,12 +1206,18 @@ ClangExpressionDeclMap::AddOneType(NameSearchContext &context, false, ClangASTContext::GetTypeQualifiers(copied_type)); - ClangASTContext::AddMethodToCXXRecordType(parser_ast_context, - copied_type, - "___clang_expr", - method_type, - lldb::eAccessPublic, - false); + const bool is_virtual = false; + const bool is_static = false; + const bool is_inline = false; + + ClangASTContext::AddMethodToCXXRecordType (parser_ast_context, + copied_type, + "___clang_expr", + method_type, + lldb::eAccessPublic, + is_virtual, + is_static, + is_inline); } context.AddTypeDecl(copied_type); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 8a4b136d51f4..44b10af68aed 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -476,7 +476,7 @@ SymbolFileDWARF::DebugRanges() const } bool -SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp) +SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp) { if (cu != NULL) { @@ -566,7 +566,7 @@ AddRangesToBlock Function * -SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die) +SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die) { DWARFDebugRanges::RangeList func_ranges; const char *name = NULL; @@ -641,7 +641,7 @@ SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) { assert (sc.comp_unit); size_t functions_added = 0; - const DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); + DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); if (dwarf_cu) { DWARFDIECollection function_dies; @@ -894,7 +894,7 @@ SymbolFileDWARF::ParseFunctionBlocks ( const SymbolContext& sc, Block *parent_block, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, addr_t subprogram_low_pc, bool parse_siblings, @@ -1011,7 +1011,7 @@ SymbolFileDWARF::ParseChildMembers ( const SymbolContext& sc, TypeSP& type_sp, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *parent_die, void *class_clang_type, const LanguageType class_language, @@ -1107,135 +1107,8 @@ SymbolFileDWARF::ParseChildMembers break; case DW_TAG_subprogram: - { - DWARFDebugInfoEntry::Attributes attributes; - is_a_class = true; - if (default_accessibility == eAccessNone) - default_accessibility = eAccessPrivate; - - //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); - // Set a bit that lets us know that we are currently parsing this - const_cast(die)->SetUserData(DIE_IS_BEING_PARSED); - - const char *mangled = NULL; - dw_offset_t type_die_offset = DW_INVALID_OFFSET; - Declaration decl; - bool is_variadic = false; - bool is_inline = false; - bool is_virtual = false; - unsigned type_quals = 0; - AccessType accessibility = default_accessibility; - - clang::FunctionDecl::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern - const char *type_name_cstr = NULL; - ConstString type_name_dbstr; - - - const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); - if (num_attributes > 0) - { - uint32_t i; - for (i=0; iGetSupportFiles().GetFileSpecAtIndex(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_name: - type_name_cstr = form_value.AsCString(&get_debug_str_data()); - break; - - case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; - case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; - case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; - //case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; - case DW_AT_external: - if (form_value.Unsigned()) - { - if (storage == clang::SC_None) - storage = clang::SC_Extern; - else - storage = clang::SC_PrivateExtern; - } - break; - case DW_AT_inline: - is_inline = form_value.Unsigned() != 0; - break; - - - case DW_AT_virtuality: - is_virtual = form_value.Unsigned() != 0; - break; - - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_address_class: - case DW_AT_artificial: - case DW_AT_calling_convention: - case DW_AT_data_location: - case DW_AT_elemental: - case DW_AT_entry_pc: - case DW_AT_explicit: - case DW_AT_frame_base: - case DW_AT_high_pc: - case DW_AT_low_pc: - case DW_AT_object_pointer: - case DW_AT_prototyped: - case DW_AT_pure: - case DW_AT_ranges: - case DW_AT_recursive: - case DW_AT_return_addr: - case DW_AT_segment: - case DW_AT_specification: - case DW_AT_start_scope: - case DW_AT_static_link: - case DW_AT_trampoline: - case DW_AT_visibility: - case DW_AT_vtable_elem_location: - case DW_AT_abstract_origin: - case DW_AT_description: - case DW_AT_sibling: - break; - } - } - } - - void *return_clang_type = NULL; - Type *func_type = ResolveTypeUID(type_die_offset); - if (func_type) - return_clang_type = func_type->GetOpaqueClangQualType(); - else - return_clang_type = type_list->GetClangASTContext().GetBuiltInType_void(); - - std::vector function_param_types; - std::vector function_param_decls; - - // Parse the function children for the parameters - bool skip_artificial = true; - - ParseChildParameters (sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls); - - void *method_function_proto = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), is_variadic, type_quals); - if (type_name_cstr) - { - clang::CXXMethodDecl *method_decl = type_list->GetClangASTContext().AddMethodToCXXRecordType (class_clang_type, - type_name_cstr, - method_function_proto, - accessibility, - is_virtual); - assert (method_decl); - //m_die_to_decl_ctx[die] = method_decl; - } - - const_cast(die)->SetUserData(type_sp.get()); - assert(type_sp.get()); - } - } + // Let the type parsing code handle this one for us... + ResolveType (dwarf_cu, die); break; case DW_TAG_inheritance: @@ -1376,7 +1249,7 @@ SymbolFileDWARF::ResolveType (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* t } CompileUnit* -SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx) +SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* cu, uint32_t cu_idx) { // Check if the symbol vendor already knows about this compile unit? if (cu->GetUserData() == NULL) @@ -2026,7 +1899,7 @@ SymbolFileDWARF::ParseChildParameters ( const SymbolContext& sc, TypeSP& type_sp, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *parent_die, bool skip_artificial, TypeList* type_list, @@ -2100,17 +1973,36 @@ SymbolFileDWARF::ParseChildParameters } } - if (skip_artificial && is_artificial) - continue; + bool skip = false; + if (skip_artificial) + { + if (is_artificial) + skip = true; + else + { + + // HACK: Objective C formal parameters "self" and "_cmd" + // are not marked as artificial in the DWARF... + CompileUnit *cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); + if (cu && (cu->GetLanguage() == eLanguageTypeObjC || cu->GetLanguage() == eLanguageTypeObjC_plus_plus)) + { + if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0)) + skip = true; + } + } + } - Type *dc_type = ResolveTypeUID(param_type_die_offset); - if (dc_type) + if (!skip) { - function_param_types.push_back (dc_type->GetOpaqueClangQualType()); + Type *type = ResolveTypeUID(param_type_die_offset); + if (type) + { + function_param_types.push_back (type->GetOpaqueClangQualType()); - clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParameterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage); - assert(param_var_decl); - function_param_decls.push_back(param_var_decl); + clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParameterDeclaration (name, type->GetOpaqueClangQualType(), storage); + assert(param_var_decl); + function_param_decls.push_back(param_var_decl); + } } } } @@ -2130,7 +2022,7 @@ SymbolFileDWARF::ParseChildEnumerators TypeSP& type_sp, void * enumerator_qual_type, uint32_t enumerator_byte_size, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *parent_die ) { @@ -2200,7 +2092,7 @@ void SymbolFileDWARF::ParseChildArrayInfo ( const SymbolContext& sc, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *parent_die, int64_t& first_index, std::vector& element_orders, @@ -2406,7 +2298,7 @@ SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset) clang::DeclContext * -SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) +SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) { DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); if (pos != m_die_to_decl_ctx.end()) @@ -2450,14 +2342,14 @@ SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DW } TypeSP -SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new) +SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new) { TypeSP type_sp; AccessType accessibility = eAccessNone; if (die != NULL) { - dw_tag_t tag = die->Tag(); + const dw_tag_t tag = die->Tag(); if (die->GetUserData() == NULL) { type_is_new = true; @@ -2840,6 +2732,9 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar Declaration decl; bool is_variadic = false; bool is_inline = false; + bool is_static = false; + bool is_virtual = false; + unsigned type_quals = 0; clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern @@ -2850,7 +2745,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar uint32_t i; for (i=0; i function_param_decls; // Parse the function children for the parameters - bool skip_artificial = false; - ParseChildParameters(sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls); + bool skip_artificial = true; + ParseChildParameters (sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls); + // clang_type will get the function prototype clang type after this call clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), is_variadic, type_quals); if (type_name_cstr) { - clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline); - // Add the decl to our DIE to decl context map - assert (function_decl); - m_die_to_decl_ctx[die] = function_decl; - if (!function_param_decls.empty()) - type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size()); + bool type_handled = false; + const DWARFDebugInfoEntry *parent_die = die->GetParent(); + if (tag == DW_TAG_subprogram) + { + if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+')) + { + // We need to find the DW_TAG_class_type or + // DW_TAG_struct_type by name so we can add this + // as a member function of the class. + const char *class_name_start = type_name_cstr + 2; + const char *class_name_end = ::strchr (class_name_start, ' '); + SymbolContext empty_sc; + void *class_opaque_type = NULL; + if (class_name_start < class_name_end) + { + ConstString class_name (class_name_start, class_name_end - class_name_start); + TypeList types; + const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types); + if (match_count > 0) + { + for (uint32_t i=0; iGetOpaqueClangQualType())) + { + class_opaque_type = type->GetOpaqueClangQualType(); + break; + } + } + } + } + + if (class_opaque_type) + { + clang::ObjCMethodDecl *objc_method_decl; + objc_method_decl = type_list->GetClangASTContext().AddMethodToObjCObjectType (class_opaque_type, + type_name_cstr, + clang_type, + accessibility); + type_handled = objc_method_decl != NULL; + } + } + else if (parent_die->Tag() == DW_TAG_class_type || + parent_die->Tag() == DW_TAG_structure_type) + { + // Look at the parent of this DIE and see if is is + // a class or struct and see if this is actually a + // C++ method + Type *class_type = ResolveType (dwarf_cu, parent_die); + if (class_type) + { + void *class_opaque_type = class_type->GetOpaqueClangQualType (); + if (ClangASTContext::IsCXXClassType (class_opaque_type)) + { + clang::CXXMethodDecl *cxx_method_decl; + cxx_method_decl = type_list->GetClangASTContext().AddMethodToCXXRecordType (class_opaque_type, + type_name_cstr, + clang_type, + accessibility, + is_virtual, + is_static, + is_inline); + type_handled = cxx_method_decl != NULL; + } + } + } + } + + if (!type_handled) + { + // We just have a function that isn't part of a class + clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline); + + // Add the decl to our DIE to decl context map + assert (function_decl); + m_die_to_decl_ctx[die] = function_decl; + if (!function_param_decls.empty()) + type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size()); + } } type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); @@ -3154,7 +3121,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar } size_t -SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children) +SymbolFileDWARF::ParseTypes (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children) { size_t types_added = 0; while (die != NULL) @@ -3296,7 +3263,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE ( const SymbolContext& sc, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, const lldb::addr_t func_low_pc ) @@ -3439,7 +3406,7 @@ size_t SymbolFileDWARF::ParseVariables ( const SymbolContext& sc, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const lldb::addr_t func_low_pc, const DWARFDebugInfoEntry *orig_die, bool parse_siblings, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 8b9906ec1e4e..0ec55da4ee1b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -162,7 +162,7 @@ public: SupportedVersion(uint16_t version); clang::DeclContext * - GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die); + GetClangDeclContextForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die); clang::DeclContext * GetClangDeclContextForDIEOffset (dw_offset_t die_offset); @@ -200,31 +200,31 @@ protected: }; DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF); - bool ParseCompileUnit(DWARFCompileUnit* cu, lldb::CompUnitSP& compile_unit_sp); + bool ParseCompileUnit (DWARFCompileUnit* cu, lldb::CompUnitSP& compile_unit_sp); DWARFCompileUnit* GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid); DWARFCompileUnit* GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu); lldb_private::CompileUnit* GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx = UINT32_MAX); bool GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, lldb_private::SymbolContext& sc); - lldb_private::Function * ParseCompileUnitFunction (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die); + lldb_private::Function * ParseCompileUnitFunction (const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die); size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc, lldb_private::Block *parent_block, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, lldb::addr_t subprogram_low_pc, bool parse_siblings, bool parse_children); - size_t ParseTypes (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children); - lldb::TypeSP ParseType (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new); + size_t ParseTypes (const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children); + lldb::TypeSP ParseType (const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new); lldb::VariableSP ParseVariableDIE( const lldb_private::SymbolContext& sc, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, const lldb::addr_t func_low_pc); size_t ParseVariables( const lldb_private::SymbolContext& sc, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const lldb::addr_t func_low_pc, const DWARFDebugInfoEntry *die, bool parse_siblings, @@ -234,7 +234,7 @@ protected: size_t ParseChildMembers( const lldb_private::SymbolContext& sc, lldb::TypeSP& type_sp, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, void *class_clang_type, const lldb::LanguageType class_language, @@ -246,7 +246,7 @@ protected: size_t ParseChildParameters( const lldb_private::SymbolContext& sc, lldb::TypeSP& type_sp, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *parent_die, bool skip_artificial, lldb_private::TypeList* type_list, @@ -258,12 +258,12 @@ protected: lldb::TypeSP& type_sp, void *enumerator_qual_type, uint32_t enumerator_byte_size, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *enum_die); void ParseChildArrayInfo( const lldb_private::SymbolContext& sc, - const DWARFCompileUnit* dwarf_cu, + DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *parent_die, int64_t& first_index, std::vector& element_orders, diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 7debcb699258..287ae7687352 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -811,7 +811,9 @@ ClangASTContext::AddMethodToCXXRecordType const char *name, void *method_opaque_type, lldb::AccessType access, - bool is_virtual + bool is_virtual, + bool is_static, + bool is_inline ) { if (!record_opaque_type || !method_opaque_type || !name) @@ -824,51 +826,56 @@ ClangASTContext::AddMethodToCXXRecordType assert(identifier_table); QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type)); - clang::Type *record_type(record_qual_type.getTypePtr()); + + clang::Type *clang_type(record_qual_type.getTypePtr()); - if (!record_type) + if (clang_type == NULL) return NULL; - RecordType *record_recty(dyn_cast(record_type)); + RecordType *record_clang_type(dyn_cast(clang_type)); - if (!record_recty) + if (record_clang_type == NULL) return NULL; - RecordDecl *record_decl = record_recty->getDecl(); + RecordDecl *record_decl = record_clang_type->getDecl(); - if (!record_decl) + if (record_decl == NULL) return NULL; CXXRecordDecl *cxx_record_decl = dyn_cast(record_decl); - if (!cxx_record_decl) + if (cxx_record_decl == NULL) return NULL; - QualType method_qual_type(QualType::getFromOpaquePtr(method_opaque_type)); + QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); + + CXXMethodDecl *cxx_method_decl = CXXMethodDecl::Create (*ast_context, + cxx_record_decl, + DeclarationNameInfo (DeclarationName (&identifier_table->get(name)), SourceLocation()), + method_qual_type, + NULL, // TypeSourceInfo * + is_static, + SC_None, + is_inline); - CXXMethodDecl *cxx_method_decl = CXXMethodDecl::Create(*ast_context, - cxx_record_decl, - DeclarationNameInfo(DeclarationName(&identifier_table->get(name)), SourceLocation()), - method_qual_type, - NULL); - clang::AccessSpecifier AS = ConvertAccessTypeToAccessSpecifier(access); + clang::AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access); - cxx_method_decl->setAccess(AS); - cxx_method_decl->setVirtualAsWritten(is_virtual); + cxx_method_decl->setAccess (access_specifier); + cxx_method_decl->setVirtualAsWritten (is_virtual); // Populate the method decl with parameter decls clang::Type *method_type(method_qual_type.getTypePtr()); - if (!method_type) + if (method_type == NULL) return NULL; - FunctionProtoType *method_funprototy(dyn_cast(method_type)); + FunctionProtoType *method_function_prototype (dyn_cast(method_type)); - if (!method_funprototy) + if (!method_function_prototype) return NULL; - unsigned int num_params = method_funprototy->getNumArgs(); + unsigned int num_params = method_function_prototype->getNumArgs(); ParmVarDecl *params[num_params]; @@ -876,20 +883,20 @@ ClangASTContext::AddMethodToCXXRecordType param_index < num_params; ++param_index) { - params[param_index] = ParmVarDecl::Create(*ast_context, - cxx_method_decl, - SourceLocation(), - NULL, // anonymous - method_funprototy->getArgType(param_index), - NULL, - SC_Auto, - SC_Auto, - NULL); + params[param_index] = ParmVarDecl::Create (*ast_context, + cxx_method_decl, + SourceLocation(), + NULL, // anonymous + method_function_prototype->getArgType(param_index), + NULL, + SC_None, + SC_None, + NULL); } - cxx_method_decl->setParams(params, num_params); + cxx_method_decl->setParams (params, num_params); - cxx_record_decl->addDecl(cxx_method_decl); + cxx_record_decl->addDecl (cxx_method_decl); return cxx_method_decl; } @@ -988,14 +995,14 @@ ClangASTContext::AddFieldToRecordType ObjCObjectType *objc_class_type = dyn_cast(clang_type); if (objc_class_type) { - bool isSynthesized = false; + bool is_synthesized = false; ClangASTContext::AddObjCClassIVar (ast_context, record_clang_type, name, field_type, access, bitfield_bit_size, - isSynthesized); + is_synthesized); } } } @@ -1250,7 +1257,7 @@ ClangASTContext::AddObjCClassIVar void *ivar_opaque_type, AccessType access, uint32_t bitfield_bit_size, - bool isSynthesized + bool is_synthesized ) { if (class_opaque_type == NULL || ivar_opaque_type == NULL) @@ -1289,7 +1296,7 @@ ClangASTContext::AddObjCClassIVar NULL, // TypeSourceInfo * ConvertAccessTypeToObjCIvarAccessControl (access), bit_width, - isSynthesized); + is_synthesized); if (field) { @@ -1334,7 +1341,132 @@ ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool } return false; } + +clang::ObjCMethodDecl * +ClangASTContext::AddMethodToObjCObjectType +( + clang::ASTContext *ast_context, + void *class_opaque_type, + const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") + void *method_opaque_type, + lldb::AccessType access +) +{ + if (class_opaque_type == NULL || method_opaque_type == NULL) + return NULL; + + IdentifierTable *identifier_table = &ast_context->Idents; + + assert (ast_context != NULL); + assert (identifier_table != NULL); + + QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); + + clang::Type *class_type = class_qual_type.getTypePtr(); + if (class_type == NULL) + return NULL; + + ObjCObjectType *objc_class_type = dyn_cast(class_type); + + if (objc_class_type == NULL) + return NULL; + + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl == NULL) + return NULL; + + const char *selector_start = ::strchr (name, ' '); + if (selector_start == NULL) + return NULL; + + selector_start++; + if (!(::isalpha (selector_start[0]) || selector_start[0] == '_')) + return NULL; + llvm::SmallVector selector_idents; + + size_t len; + const char *start; + for (start = selector_start, len = ::strcspn(start, ":]"); + start && *start != '\0' && *start != ']'; + start += len + 1) + { + selector_idents.push_back (&identifier_table->get (StringRef (start, len))); + } + + + if (selector_idents.size() == 0) + return 0; + + clang::Selector method_selector = ast_context->Selectors.getSelector (selector_idents.size(), + selector_idents.data()); + + QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); + + // Populate the method decl with parameter decls + clang::Type *method_type(method_qual_type.getTypePtr()); + + if (method_type == NULL) + return NULL; + + FunctionProtoType *method_function_prototype (dyn_cast(method_type)); + + if (!method_function_prototype) + return NULL; + + + bool is_variadic = false; + bool is_synthesized = false; + bool is_defined = false; + ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None; + + const unsigned num_args = method_function_prototype->getNumArgs(); + + ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context, + SourceLocation(), // beginLoc, + SourceLocation(), // endLoc, + method_selector, + method_function_prototype->getResultType(), + NULL, // TypeSourceInfo *ResultTInfo, + GetDeclContextForType (class_opaque_type), + name[0] == '-', + is_variadic, + is_synthesized, + is_defined, + imp_control, + num_args); + + + if (objc_method_decl == NULL) + return NULL; + + if (num_args > 0) + { + llvm::SmallVector params; + + for (int param_index = 0; param_index < num_args; ++param_index) + { + params.push_back (ParmVarDecl::Create (*ast_context, + objc_method_decl, + SourceLocation(), + NULL, // anonymous + method_function_prototype->getArgType(param_index), + NULL, + SC_Auto, + SC_Auto, + NULL)); + } + + objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args); + } + class_interface_decl->addDecl (objc_method_decl); + + + return objc_method_decl; +} + + #pragma mark Aggregate Types @@ -3044,6 +3176,32 @@ ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &i return false; } +bool +ClangASTContext::IsCXXClassType (void *clang_type) +{ + if (clang_type) + { + QualType qual_type (QualType::getFromOpaquePtr(clang_type)); + if (qual_type->getAsCXXRecordDecl() != NULL) + return true; + } + return false; +} + +bool +ClangASTContext::IsObjCClassType (void *clang_type) +{ + if (clang_type) + { + QualType qual_type (QualType::getFromOpaquePtr(clang_type)); + if (qual_type->isObjCObjectOrInterfaceType()) + return true; + } + return false; +} + + + bool ClangASTContext::IsCStringType (void *clang_type, uint32_t &length) -- GitLab