[Lldb-commits] [lldb] r141908 - in /lldb/trunk: include/lldb/Symbol/ClangASTContext.h source/Commands/CommandObjectTarget.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp source/Symbol/ClangASTContext.cpp

Greg Clayton gclayton at apple.com
Thu Oct 13 16:13:20 PDT 2011


Author: gclayton
Date: Thu Oct 13 18:13:20 2011
New Revision: 141908

URL: http://llvm.org/viewvc/llvm-project?rev=141908&view=rev
Log:
Fixed a case where we might end up trying to parse a type in the DWARF parser for a method whose class isn't currently in the process of completing itself. Currently, methods of a class, must be parsed when the class type that contains the method is asked to complete itself through the clang::ExternalASTSource virtual functions. Now we "do the right thing" by checking if the class is being defined, and if so we parse it, else we tell the class to complete itself so everything happens correctly.


Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/source/Commands/CommandObjectTarget.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    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=141908&r1=141907&r2=141908&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Thu Oct 13 18:13:20 2011
@@ -722,6 +722,9 @@
     IsCXXClassType (lldb::clang_type_t clang_type);
     
     static bool
+    IsBeingDefined (lldb::clang_type_t clang_type);
+    
+    static bool
     IsObjCClassType (lldb::clang_type_t clang_type);
 
     static bool

Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=141908&r1=141907&r2=141908&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Thu Oct 13 18:13:20 2011
@@ -658,11 +658,6 @@
                                                                                    target,
                                                                                    variable_list,
                                                                                    valobj_list));
-                        
-//                        matches = target->GetImages().FindGlobalVariables (ConstString(arg),
-//                                                                                   true, 
-//                                                                                   UINT32_MAX, 
-//                                                                                   variable_list);
                         matches = variable_list.GetSize();
                     }
                     

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=141908&r1=141907&r2=141908&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Thu Oct 13 18:13:20 2011
@@ -34,6 +34,8 @@
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/Value.h"
 
+#include "lldb/Host/Host.h"
+
 #include "lldb/Symbol/Block.h"
 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
 #include "lldb/Symbol/CompileUnit.h"
@@ -4275,32 +4277,67 @@
                                         clang_type_t class_opaque_type = class_type->GetClangForwardType();
                                         if (ClangASTContext::IsCXXClassType (class_opaque_type))
                                         {
-                                            // Neither GCC 4.2 nor clang++ currently set a valid accessibility
-                                            // in the DWARF for C++ methods... Default to public for now...
-                                            if (accessibility == eAccessNone)
-                                                accessibility = eAccessPublic;
-                                            
-                                            if (!is_static && !die->HasChildren())
+                                            if (ClangASTContext::IsBeingDefined (class_opaque_type))
                                             {
-                                                // We have a C++ member function with no children (this pointer!)
-                                                // and clang will get mad if we try and make a function that isn't
-                                                // well formed in the DWARF, so we will just skip it...
-                                                type_handled = true;
+                                                // Neither GCC 4.2 nor clang++ currently set a valid accessibility
+                                                // in the DWARF for C++ methods... Default to public for now...
+                                                if (accessibility == eAccessNone)
+                                                    accessibility = eAccessPublic;
+                                                
+                                                if (!is_static && !die->HasChildren())
+                                                {
+                                                    // We have a C++ member function with no children (this pointer!)
+                                                    // and clang will get mad if we try and make a function that isn't
+                                                    // well formed in the DWARF, so we will just skip it...
+                                                    type_handled = true;
+                                                }
+                                                else
+                                                {
+                                                    clang::CXXMethodDecl *cxx_method_decl;
+                                                    // REMOVE THE CRASH DESCRIPTION BELOW
+                                                    Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8x from %s/%s", 
+                                                                                         type_name_cstr, 
+                                                                                         class_type->GetName().GetCString(),
+                                                                                         die->GetOffset(),
+                                                                                         m_obj_file->GetFileSpec().GetDirectory().GetCString(),
+                                                                                         m_obj_file->GetFileSpec().GetFilename().GetCString());
+
+                                                    cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type, 
+                                                                                                    type_name_cstr,
+                                                                                                    clang_type,
+                                                                                                    accessibility,
+                                                                                                    is_virtual,
+                                                                                                    is_static,
+                                                                                                    is_inline,
+                                                                                                    is_explicit);
+                                                    LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
+
+                                                    type_handled = cxx_method_decl != NULL;
+                                                }
                                             }
                                             else
                                             {
-                                                clang::CXXMethodDecl *cxx_method_decl;
-                                                cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type, 
-                                                                                                type_name_cstr,
-                                                                                                clang_type,
-                                                                                                accessibility,
-                                                                                                is_virtual,
-                                                                                                is_static,
-                                                                                                is_inline,
-                                                                                                is_explicit);
-                                                LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
-
-                                                type_handled = cxx_method_decl != NULL;
+                                                // We were asked to parse the type for a method in a class, yet the
+                                                // class hasn't been asked to complete itself through the 
+                                                // clang::ExternalASTSource protocol, so we need to just have the
+                                                // class complete itself and do things the right way, then our 
+                                                // DIE should then have an entry in the m_die_to_type map. First 
+                                                // we need to modify the m_die_to_type so it doesn't think we are 
+                                                // trying to parse this DIE anymore...
+                                                m_die_to_type[die] = NULL;
+                                                
+                                                // Now we get the full type to force our class type to complete itself 
+                                                // using the clang::ExternalASTSource protocol which will parse all 
+                                                // base classes and all methods (including the method for this DIE).
+                                                class_type->GetClangFullType();
+
+                                                // The type for this DIE should have been filled in the function call above
+                                                type_ptr = m_die_to_type[die];
+                                                if (type_ptr)
+                                                {
+                                                    type_sp = type_list->FindType(type_ptr->GetID());
+                                                    break;
+                                                }
                                             }
                                         }
                                     }

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=141908&r1=141907&r2=141908&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Oct 13 18:13:20 2011
@@ -4998,6 +4998,19 @@
     return false;
 }
 
+bool
+ClangASTContext::IsBeingDefined (lldb::clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type);
+        if (tag_type)
+            return tag_type->isBeingDefined();
+    }
+    return false;
+}
+
 bool 
 ClangASTContext::IsObjCClassType (clang_type_t clang_type)
 {





More information about the lldb-commits mailing list