[Lldb-commits] [lldb] r114722 - in /lldb/trunk: include/lldb/Symbol/ClangASTContext.h lldb.xcodeproj/project.pbxproj source/Expression/ClangExpressionDeclMap.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h source/Symbol/ClangASTContext.cpp

Greg Clayton gclayton at apple.com
Thu Sep 23 22:15:53 PDT 2010


Author: gclayton
Date: Fri Sep 24 00:15:53 2010
New Revision: 114722

URL: http://llvm.org/viewvc/llvm-project?rev=114722&view=rev
Log:
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++.


Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/trunk/source/Symbol/ClangASTContext.cpp

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=114722&r1=114721&r2=114722&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Fri Sep 24 00:15:53 2010
@@ -174,12 +174,12 @@
                           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 @@
                               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 @@
     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 @@
     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, 

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=114722&r1=114721&r2=114722&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Sep 24 00:15:53 2010
@@ -2432,6 +2432,7 @@
 			isa = PBXProject;
 			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
 			compatibilityVersion = "Xcode 3.1";
+			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
 				en,

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=114722&r1=114721&r2=114722&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri Sep 24 00:15:53 2010
@@ -1206,12 +1206,18 @@
                                                                  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);

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=114722&r1=114721&r2=114722&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Sep 24 00:15:53 2010
@@ -476,7 +476,7 @@
 }
 
 bool
-SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
+SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
 {
     if (cu != NULL)
     {
@@ -566,7 +566,7 @@
 
 
 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 @@
 {
     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 @@
 (
     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 @@
 (
     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 @@
             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<DWARFDebugInfoEntry*>(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; i<num_attributes; ++i)
-                    {
-                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
-                        DWARFFormValue form_value;
-                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
-                        {
-                            switch (attr)
-                            {
-                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().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<void *> function_param_types;
-                    std::vector<clang::ParmVarDecl*> 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<DWARFDebugInfoEntry*>(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 @@
 }
 
 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 @@
 (
     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 @@
                         }
                     }
 
-                    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 @@
     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 @@
 SymbolFileDWARF::ParseChildArrayInfo
 (
     const SymbolContext& sc,
-    const DWARFCompileUnit* dwarf_cu,
+    DWARFCompileUnit* dwarf_cu,
     const DWARFDebugInfoEntry *parent_die,
     int64_t& first_index,
     std::vector<uint64_t>& element_orders,
@@ -2406,7 +2298,7 @@
 
 
 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 @@
 }
 
 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 @@
                     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 @@
                         uint32_t i;
                         for (i=0; i<num_attributes; ++i)
                         {
-                            attr = attributes.AttributeAtIndex(i);
+                            const dw_attr_t attr = attributes.AttributeAtIndex(i);
                             DWARFFormValue form_value;
                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                             {
@@ -2868,6 +2763,8 @@
                                 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_inline:              is_inline = form_value.Unsigned() != 0; break;
+                                case DW_AT_virtuality:          is_virtual = form_value.Unsigned() != 0;  break;
                                 case DW_AT_external:
                                     if (form_value.Unsigned())
                                     {
@@ -2877,9 +2774,6 @@
                                             storage = clang::SC_PrivateExtern;
                                     }
                                     break;
-                                case DW_AT_inline:
-                                    is_inline = form_value.Unsigned() != 0;
-                                    break;
 
                                 case DW_AT_allocated:
                                 case DW_AT_associated:
@@ -2905,7 +2799,6 @@
                                 case DW_AT_static_link:
                                 case DW_AT_trampoline:
                                 case DW_AT_visibility:
-                                case DW_AT_virtuality:
                                 case DW_AT_vtable_elem_location:
                                 case DW_AT_abstract_origin:
                                 case DW_AT_description:
@@ -2926,18 +2819,92 @@
                         std::vector<clang::ParmVarDecl*> 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; i<match_count; ++i)
+                                            {
+                                                Type *type = types.GetTypeAtIndex (i).get();
+                                                if (ClangASTContext::IsObjCClassType (type->GetOpaqueClangQualType()))
+                                                {
+                                                    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 @@
 }
 
 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 @@
 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 @@
 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,

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=114722&r1=114721&r2=114722&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Fri Sep 24 00:15:53 2010
@@ -162,7 +162,7 @@
     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 @@
     };
 
     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 @@
     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 @@
     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 @@
                                 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<uint64_t>& element_orders,

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=114722&r1=114721&r2=114722&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Sep 24 00:15:53 2010
@@ -811,7 +811,9 @@
     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 @@
     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<RecordType>(record_type));
+    RecordType *record_clang_type(dyn_cast<RecordType>(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<CXXRecordDecl>(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<FunctionProtoType>(method_type));
+    FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(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 @@
          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 @@
             ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(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 @@
     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 @@
                                                             NULL, // TypeSourceInfo *
                                                             ConvertAccessTypeToObjCIvarAccessControl (access),
                                                             bit_width,
-                                                            isSynthesized);
+                                                            is_synthesized);
                 
                 if (field)
                 {
@@ -1334,7 +1341,132 @@
     }
     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<ObjCObjectType>(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<IdentifierInfo *, 12> 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<FunctionProtoType>(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<ParmVarDecl *, 12> 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 @@
     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)





More information about the lldb-commits mailing list