<rdar://problem/11082392>

Fixed an issue that could cause circular type parsing that will assert and kill LLDB.

Prior to this fix the DWARF parser would always create class types and not start their definitions (for both C++ and ObjC classes) until we were asked to complete the class later. When we had cases like:

class A
{
    class B
    {
    };
};

We would alway try to complete A before specifying "A" as the decl context for B. Turns out we can just start the definition and still not complete the class since we can check the TagDecl::isCompleteDefinition() function. This only works for C++ types. This means we will not be pulling in the full definition of parent classes all the time and should help with our memory consumption and also reduce the amount of debug info we have to parse.

I also reduced redundant code that was checking in a lldb::clang_type_t was a possible C++ dynamic type since it was still completing the type, just to see if it was dynamic. This was fixed in another function that was checking for a type being dynamic as an ObjC or a C++ type, but there was dedicated fucntion for C++ that we missed.

llvm-svn: 153713
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 899928c..f06a954 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -79,23 +79,23 @@
 using namespace lldb;
 using namespace lldb_private;
 
-static inline bool
-child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
-{
-    switch (tag)
-    {
-    default:
-        break;
-    case DW_TAG_subprogram:
-    case DW_TAG_inlined_subroutine:
-    case DW_TAG_class_type:
-    case DW_TAG_structure_type:
-    case DW_TAG_union_type:
-        return true;
-    }
-    return false;
-}
-
+//static inline bool
+//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
+//{
+//    switch (tag)
+//    {
+//    default:
+//        break;
+//    case DW_TAG_subprogram:
+//    case DW_TAG_inlined_subroutine:
+//    case DW_TAG_class_type:
+//    case DW_TAG_structure_type:
+//    case DW_TAG_union_type:
+//        return true;
+//    }
+//    return false;
+//}
+//
 static AccessType
 DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
 {
@@ -1874,23 +1874,23 @@
                                                               DW_TAG_value_to_name(die->Tag()), 
                                                               die->GetName(this, cu), 
                                                               decl_ctx_die->GetOffset());
-
-                Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
-                if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
-                {
-                    if (log)
-                        GetObjectFile()->GetModule()->LogMessage (log.get(), 
-                                                                  "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function", 
-                                                                  die->GetOffset(), 
-                                                                  DW_TAG_value_to_name(die->Tag()), 
-                                                                  die->GetName(this, cu), 
-                                                                  decl_ctx_die->GetOffset());
-                    // Ask the type to complete itself if it already hasn't since if we
-                    // want a function (method or static) from a class, the class must 
-                    // create itself and add it's own methods and class functions.
-                    if (parent_type)
-                        parent_type->GetClangFullType();
-                }
+//
+//                Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
+//                if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
+//                {
+//                    if (log)
+//                        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+//                                                                  "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function", 
+//                                                                  die->GetOffset(), 
+//                                                                  DW_TAG_value_to_name(die->Tag()), 
+//                                                                  die->GetName(this, cu), 
+//                                                                  decl_ctx_die->GetOffset());
+//                    // Ask the type to complete itself if it already hasn't since if we
+//                    // want a function (method or static) from a class, the class must 
+//                    // create itself and add it's own methods and class functions.
+//                    if (parent_type)
+//                        parent_type->GetClangFullType();
+//                }
             }
             break;
 
@@ -1963,7 +1963,6 @@
         {
             LayoutInfo layout_info;
             
-            ast.StartTagDeclarationDefinition (clang_type);
             {
                 if (die->HasChildren())
                 {
@@ -1971,7 +1970,12 @@
                     LanguageType class_language = eLanguageTypeUnknown;
                     bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
                     if (is_objc_class)
+                    {
                         class_language = eLanguageTypeObjC;
+                        // For objective C we don't start the definition when
+                        // the class is created.
+                        ast.StartTagDeclarationDefinition (clang_type);
+                    }
                     
                     int tag_decl_kind = -1;
                     AccessType default_accessibility = eAccessNone;
@@ -5076,7 +5080,11 @@
                                                        unique_ast_entry);
                     
                     if (!is_forward_declaration)
-                    {                    
+                    {
+                        // Always start the definition for a class type so that
+                        // if the class has child classes or types that require
+                        // the class to be created for use as their decl contexts
+                        // the class will be ready to accept these child definitions.
                         if (die->HasChildren() == false)
                         {
                             // No children for this struct/union/class, lets finish it
@@ -5085,6 +5093,17 @@
                         }
                         else if (clang_type_was_created)
                         {
+                            // Start the definition if the class is not objective C since
+                            // the underlying decls respond to isCompleteDefinition(). Objective
+                            // C decls dont' respond to isCompleteDefinition() so we can't
+                            // start the declaration definition right away. For C++ classs/union/structs
+                            // we want to start the definition in case the class is needed as the
+                            // declaration context for a contained class or type without the need
+                            // to complete that type..
+                            
+                            if (class_language != eLanguageTypeObjC)
+                                ast.StartTagDeclarationDefinition (clang_type);
+
                             // Leave this as a forward declaration until we need
                             // to know the details of the type. lldb_private::Type
                             // will automatically call the SymbolFile virtual function