Fixed the forward declaration issue that was present in the DWARF parser after
adding methods to C++ and objective C classes. In order to make methods, we
need the function prototype which means we need the arguments. Parsing these
could cause a circular reference that caused an  assertion.

Added a new typedef for the clang opaque types which are just void pointers:
lldb::clang_type_t. This appears in lldb-types.h.

This was fixed by enabling struct, union, class, and enum types to only get
a forward declaration when we make the clang opaque qual type for these
types. When they need to actually be resolved, lldb_private::Type will call
a new function in the SymbolFile protocol to resolve a clang type when it is
not fully defined (clang::TagDecl::getDefinition() returns NULL). This allows
us to be a lot more lazy when parsing clang types and keeps down the amount
of data that gets parsed into the ASTContext for each module. 

Getting the clang type from a "lldb_private::Type" object now takes a boolean
that indicates if a forward declaration is ok:

    clang_type_t lldb_private::Type::GetClangType (bool forward_decl_is_ok);
    
So function prototypes that define parameters that are "const T&" can now just
parse the forward declaration for type 'T' and we avoid circular references in
the type system.



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@115012 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index cf223b4..a0f483b 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -398,7 +398,7 @@
     return false;
 }
 
-void *
+clang_type_t
 ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
 {
     ASTContext *ast_context = getASTContext();
@@ -408,8 +408,8 @@
     return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
 }
 
-void *
-ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
+clang_type_t
+ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
 {
     if (!ast_context)
         return NULL;
@@ -468,7 +468,7 @@
     return NULL;
 }
 
-void *
+clang_type_t
 ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
 {
     ASTContext *ast_context = getASTContext();
@@ -657,31 +657,31 @@
     return NULL;
 }
 
-void *
-ClangASTContext::GetBuiltInType_void(clang::ASTContext *ast_context)
+clang_type_t
+ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
 {
     return ast_context->VoidTy.getAsOpaquePtr();
 }
 
-void *
+clang_type_t
 ClangASTContext::GetBuiltInType_objc_id()
 {
     return getASTContext()->getObjCIdType().getAsOpaquePtr();
 }
 
-void *
+clang_type_t
 ClangASTContext::GetBuiltInType_objc_Class()
 {
     return getASTContext()->getObjCClassType().getAsOpaquePtr();
 }
 
-void *
+clang_type_t
 ClangASTContext::GetBuiltInType_objc_selector()
 {
     return getASTContext()->getObjCSelType().getAsOpaquePtr();
 }
 
-void *
+clang_type_t
 ClangASTContext::GetCStringType (bool is_const)
 {
     QualType char_type(getASTContext()->CharTy);
@@ -692,14 +692,14 @@
     return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
 }
 
-void *
+clang_type_t
 ClangASTContext::GetVoidPtrType (bool is_const)
 {
     return GetVoidPtrType(getASTContext(), is_const);
 }
 
-void *
-ClangASTContext::GetVoidPtrType (clang::ASTContext *ast_context, bool is_const)
+clang_type_t
+ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
 {
     QualType void_ptr_type(ast_context->VoidPtrTy);
     
@@ -709,10 +709,10 @@
     return void_ptr_type.getAsOpaquePtr();
 }
 
-void *
-ClangASTContext::CopyType(clang::ASTContext *dest_context, 
-                          clang::ASTContext *source_context,
-                          void *clang_type)
+clang_type_t
+ClangASTContext::CopyType (ASTContext *dest_context, 
+                           ASTContext *source_context,
+                           clang_type_t clang_type)
 {
     Diagnostic diagnostics;
     FileManager file_manager;
@@ -724,9 +724,9 @@
 }
 
 bool
-ClangASTContext::AreTypesSame(clang::ASTContext *ast_context,
-             void *type1,
-             void *type2)
+ClangASTContext::AreTypesSame(ASTContext *ast_context,
+             clang_type_t type1,
+             clang_type_t type2)
 {
     return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
                                     QualType::getFromOpaquePtr(type2));
@@ -734,8 +734,8 @@
 
 #pragma mark CVR modifiers
 
-void *
-ClangASTContext::AddConstModifier (void *clang_type)
+clang_type_t
+ClangASTContext::AddConstModifier (clang_type_t clang_type)
 {
     if (clang_type)
     {
@@ -746,8 +746,8 @@
     return NULL;
 }
 
-void *
-ClangASTContext::AddRestrictModifier (void *clang_type)
+clang_type_t
+ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
 {
     if (clang_type)
     {
@@ -758,8 +758,8 @@
     return NULL;
 }
 
-void *
-ClangASTContext::AddVolatileModifier (void *clang_type)
+clang_type_t
+ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
 {
     if (clang_type)
     {
@@ -772,7 +772,7 @@
 
 #pragma mark Structure, Unions, Classes
 
-void *
+clang_type_t
 ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
 {
     ASTContext *ast_context = getASTContext();
@@ -806,10 +806,10 @@
 CXXMethodDecl *
 ClangASTContext::AddMethodToCXXRecordType
 (
-    clang::ASTContext *ast_context,
-    void *record_opaque_type,
+    ASTContext *ast_context,
+    clang_type_t record_opaque_type,
     const char *name,
-    void *method_opaque_type,
+    clang_type_t method_opaque_type,
     lldb::AccessType access,
     bool is_virtual,
     bool is_static,
@@ -859,7 +859,7 @@
                                                             is_inline);
     
     
-    clang::AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
+    AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
     
     cxx_method_decl->setAccess (access_specifier);
     cxx_method_decl->setVirtualAsWritten (is_virtual);
@@ -904,10 +904,10 @@
 bool
 ClangASTContext::AddFieldToRecordType 
 (
-    clang::ASTContext *ast_context,
-    void *record_clang_type, 
+    ASTContext *ast_context,
+    clang_type_t record_clang_type, 
     const char *name, 
-    void *field_type, 
+    clang_type_t field_type, 
     AccessType access, 
     uint32_t bitfield_bit_size
 )
@@ -1069,7 +1069,7 @@
 }
 
 void
-ClangASTContext::SetDefaultAccessForRecordFields (void *clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
+ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
 {
     if (clang_qual_type)
     {
@@ -1102,7 +1102,7 @@
 #pragma mark C++ Base Classes
 
 CXXBaseSpecifier *
-ClangASTContext::CreateBaseClassSpecifier (void *base_class_type, AccessType access, bool is_virtual, bool base_of_class)
+ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
 {
     if (base_class_type)
         return new CXXBaseSpecifier (SourceRange(), 
@@ -1124,7 +1124,7 @@
 }
 
 bool
-ClangASTContext::SetBaseClassesForClassType (void *class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
+ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
 {
     if (class_clang_type)
     {
@@ -1188,7 +1188,7 @@
 }
 #pragma mark Objective C Classes
 
-void *
+clang_type_t
 ClangASTContext::CreateObjCClass 
 (
     const char *name, 
@@ -1220,7 +1220,7 @@
 }
 
 bool
-ClangASTContext::SetObjCSuperClass (void *class_opaque_type, void *super_opaque_type)
+ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
 {
     if (class_opaque_type && super_opaque_type)
     {
@@ -1251,10 +1251,10 @@
 bool
 ClangASTContext::AddObjCClassIVar 
 (
-    clang::ASTContext *ast_context,
-    void *class_opaque_type, 
+    ASTContext *ast_context,
+    clang_type_t class_opaque_type, 
     const char *name, 
-    void *ivar_opaque_type, 
+    clang_type_t ivar_opaque_type, 
     AccessType access, 
     uint32_t bitfield_bit_size, 
     bool is_synthesized
@@ -1311,7 +1311,7 @@
 
 
 bool
-ClangASTContext::ObjCTypeHasIVars (void *class_opaque_type, bool check_superclass)
+ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
 {
     QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
 
@@ -1342,13 +1342,13 @@
     return false;            
 }
 
-clang::ObjCMethodDecl *
+ObjCMethodDecl *
 ClangASTContext::AddMethodToObjCObjectType
 (
-    clang::ASTContext *ast_context,
-    void *class_opaque_type, 
+    ASTContext *ast_context,
+    clang_type_t class_opaque_type, 
     const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
-    void *method_opaque_type,
+    clang_type_t method_opaque_type,
     lldb::AccessType access
 )
 {
@@ -1471,7 +1471,7 @@
 #pragma mark Aggregate Types
 
 bool
-ClangASTContext::IsAggregateType (void *clang_type)
+ClangASTContext::IsAggregateType (clang_type_t clang_type)
 {
     if (clang_type == NULL)
         return false;
@@ -1505,7 +1505,7 @@
 }
 
 uint32_t
-ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_classes)
+ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
 {
     if (clang_qual_type == NULL)
         return 0;
@@ -1642,11 +1642,11 @@
 }
 
 
-void *
+clang_type_t
 ClangASTContext::GetChildClangTypeAtIndex
 (
     const char *parent_name,
-    void *parent_clang_type,
+    clang_type_t parent_clang_type,
     uint32_t idx,
     bool transparent_pointers,
     bool omit_empty_base_classes,
@@ -1673,12 +1673,12 @@
     return NULL;
 }
 
-void *
+clang_type_t
 ClangASTContext::GetChildClangTypeAtIndex
 (
     ASTContext *ast_context,
     const char *parent_name,
-    void *parent_clang_type,
+    clang_type_t parent_clang_type,
     uint32_t idx,
     bool transparent_pointers,
     bool omit_empty_base_classes,
@@ -2186,7 +2186,7 @@
 ClangASTContext::GetIndexOfChildMemberWithName
 (
     ASTContext *ast_context,
-    void *clang_type,
+    clang_type_t clang_type,
     const char *name,
     bool omit_empty_base_classes,
     std::vector<uint32_t>& child_indexes
@@ -2464,7 +2464,7 @@
 ClangASTContext::GetIndexOfChildWithName
 (
     ASTContext *ast_context,
-    void *clang_type,
+    clang_type_t clang_type,
     const char *name,
     bool omit_empty_base_classes
 )
@@ -2668,7 +2668,7 @@
 #pragma mark TagType
 
 bool
-ClangASTContext::SetTagTypeKind (void *tag_clang_type, int kind)
+ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
 {
     if (tag_clang_type)
     {
@@ -2695,7 +2695,7 @@
 #pragma mark DeclContext Functions
 
 DeclContext *
-ClangASTContext::GetDeclContextForType (void *clang_type)
+ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
 {
     if (clang_type == NULL)
         return NULL;
@@ -2756,7 +2756,7 @@
 #pragma mark Function Types
 
 FunctionDecl *
-ClangASTContext::CreateFunctionDeclaration (const char *name, void *function_clang_type, int storage, bool is_inline)
+ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
 {
     if (name)
     {
@@ -2791,10 +2791,10 @@
     return NULL;
 }
 
-void *
-ClangASTContext::CreateFunctionType (clang::ASTContext *ast_context,
-                                     void *result_type, 
-                                     void **args, 
+clang_type_t
+ClangASTContext::CreateFunctionType (ASTContext *ast_context,
+                                     clang_type_t result_type, 
+                                     clang_type_t *args, 
                                      unsigned num_args, 
                                      bool is_variadic, 
                                      unsigned type_quals)
@@ -2818,7 +2818,7 @@
 }
 
 ParmVarDecl *
-ClangASTContext::CreateParameterDeclaration (const char *name, void *param_type, int storage)
+ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
 {
     ASTContext *ast_context = getASTContext();
     assert (ast_context != NULL);
@@ -2843,8 +2843,8 @@
 
 #pragma mark Array Types
 
-void *
-ClangASTContext::CreateArrayType (void *element_type, size_t element_count, uint32_t bit_stride)
+clang_type_t
+ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
 {
     if (element_type)
     {
@@ -2863,7 +2863,7 @@
 #pragma mark TagDecl
 
 bool
-ClangASTContext::StartTagDeclarationDefinition (void *clang_type)
+ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
 {
     if (clang_type)
     {
@@ -2887,7 +2887,7 @@
 }
 
 bool
-ClangASTContext::CompleteTagDeclarationDefinition (void *clang_type)
+ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
 {
     if (clang_type)
     {
@@ -2913,8 +2913,8 @@
 
 #pragma mark Enumeration Types
 
-void *
-ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, void *integer_qual_type)
+clang_type_t
+ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
 {
     // TODO: Do something intelligent with the Declaration object passed in
     // like maybe filling in the SourceLocation with it...
@@ -2935,11 +2935,29 @@
     return NULL;
 }
 
+clang_type_t
+ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
+{
+    QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
+
+    clang::Type *clang_type = enum_qual_type.getTypePtr();
+    if (clang_type)
+    {
+        const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
+        if (enum_type)
+        {
+            EnumDecl *enum_decl = enum_type->getDecl();
+            if (enum_decl)
+                return enum_decl->getIntegerType().getAsOpaquePtr();
+        }
+    }
+    return NULL;
+}
 bool
 ClangASTContext::AddEnumerationValueToEnumerationType
 (
-    void *enum_clang_type,
-    void *enumerator_clang_type,
+    clang_type_t enum_clang_type,
+    clang_type_t enumerator_clang_type,
     const Declaration &decl,
     const char *name,
     int64_t enum_value,
@@ -2988,8 +3006,8 @@
 
 #pragma mark Pointers & References
 
-void *
-ClangASTContext::CreatePointerType (void *clang_type)
+clang_type_t
+ClangASTContext::CreatePointerType (clang_type_t clang_type)
 {
     if (clang_type)
     {
@@ -3009,24 +3027,24 @@
     return NULL;
 }
 
-void *
-ClangASTContext::CreateLValueReferenceType (void *clang_type)
+clang_type_t
+ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
 {
     if (clang_type)
         return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
     return NULL;
 }
 
-void *
-ClangASTContext::CreateRValueReferenceType (void *clang_type)
+clang_type_t
+ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
 {
     if (clang_type)
         return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
     return NULL;
 }
 
-void *
-ClangASTContext::CreateMemberPointerType (void *clang_pointee_type, void *clang_class_type)
+clang_type_t
+ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
 {
     if (clang_pointee_type && clang_pointee_type)
         return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
@@ -3042,7 +3060,7 @@
 }
 
 bool
-ClangASTContext::IsPointerOrReferenceType (void *clang_type, void **target_type)
+ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
 {
     if (clang_type == NULL)
         return false;
@@ -3084,7 +3102,7 @@
 }
 
 bool
-ClangASTContext::IsIntegerType (void *clang_type, bool &is_signed)
+ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
 {
     if (!clang_type)
         return false;
@@ -3104,7 +3122,7 @@
 }
 
 bool
-ClangASTContext::IsPointerType (void *clang_type, void **target_type)
+ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
 {
     if (clang_type)
     {
@@ -3138,7 +3156,7 @@
 }
 
 bool
-ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex)
+ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
 {
     if (clang_type)
     {
@@ -3177,7 +3195,7 @@
 }
 
 bool
-ClangASTContext::IsCXXClassType (void *clang_type)
+ClangASTContext::IsCXXClassType (clang_type_t clang_type)
 {
     if (clang_type)
     {
@@ -3189,7 +3207,7 @@
 }
 
 bool 
-ClangASTContext::IsObjCClassType (void *clang_type)
+ClangASTContext::IsObjCClassType (clang_type_t clang_type)
 {
     if (clang_type)
     {
@@ -3204,7 +3222,7 @@
 
 
 bool
-ClangASTContext::IsCStringType (void *clang_type, uint32_t &length)
+ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
 {
     if (clang_type)
     {
@@ -3268,7 +3286,7 @@
 }
 
 bool
-ClangASTContext::IsFunctionPointerType (void *clang_type)
+ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
 {
     if (clang_type)
     {
@@ -3300,7 +3318,7 @@
 
 
 bool
-ClangASTContext::IsArrayType (void *clang_type, void **member_type, uint64_t *size)
+ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
 {
     if (!clang_type)
         return false;
@@ -3340,8 +3358,8 @@
 
 #pragma mark Typedefs
 
-void *
-ClangASTContext::CreateTypedefType (const char *name, void *clang_type, DeclContext *decl_ctx)
+clang_type_t
+ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
 {
     if (clang_type)
     {
@@ -3366,16 +3384,16 @@
 
 
 std::string
-ClangASTContext::GetTypeName (void *opaque_qual_type)
+ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
 {
     std::string return_name;
     
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_qual_type));
+    QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
 
-    const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
+    const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
     if (typedef_type)
     {
-        const clang::TypedefDecl *typedef_decl = typedef_type->getDecl();
+        const TypedefDecl *typedef_decl = typedef_type->getDecl();
         return_name = typedef_decl->getQualifiedNameAsString();
     }
     else
@@ -3393,7 +3411,7 @@
 // so we can support remote targets. The code below also requires a patch to
 // llvm::APInt.
 //bool
-//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, void *clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
+//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, clang_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
 //{
 //  uint32_t count = 0;
 //  bool is_complex = false;
@@ -3428,7 +3446,7 @@
 //}
 
 size_t
-ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, void *clang_type, const char *s, uint8_t *dst, size_t dst_size)
+ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
 {
     if (clang_type)
     {
@@ -3467,7 +3485,7 @@
 }
 
 unsigned
-ClangASTContext::GetTypeQualifiers(void *clang_type)
+ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
 {
     assert (clang_type);
     
diff --git a/source/Symbol/ClangASTType.cpp b/source/Symbol/ClangASTType.cpp
index 64e1c71..cccec2a 100644
--- a/source/Symbol/ClangASTType.cpp
+++ b/source/Symbol/ClangASTType.cpp
@@ -804,6 +804,29 @@
     return 0;
 }
 
+
+bool
+ClangASTType::IsDefined()
+{
+    return ClangASTType::IsDefined (m_type);
+}
+
+
+bool
+ClangASTType::IsDefined (void *opaque_clang_qual_type)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
+    clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
+    if (tag_type)
+    {
+        clang::TagDecl *tag_decl = tag_type->getDecl();
+        if (tag_decl)
+            return tag_decl->getDefinition() != NULL;
+        return false;
+    }
+    return true;
+}
+
 void
 ClangASTType::DumpTypeDescription (Stream *s)
 {
diff --git a/source/Symbol/Function.cpp b/source/Symbol/Function.cpp
index 3c108d7..41a708c 100644
--- a/source/Symbol/Function.cpp
+++ b/source/Symbol/Function.cpp
@@ -402,7 +402,7 @@
 Type
 Function::GetReturnType ()
 {
-    clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetOpaqueClangQualType()));
+    clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangType()));
     assert (clang_type->isFunctionType());
     clang::FunctionType *function_type = dyn_cast<clang::FunctionType> (clang_type);
     clang::QualType fun_return_qualtype = function_type->getResultType();
@@ -421,7 +421,7 @@
 int
 Function::GetArgumentCount ()
 {
-    clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetOpaqueClangQualType()));
+    clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangType()));
     assert (clang_type->isFunctionType());
     if (!clang_type->isFunctionProtoType())
         return -1;
@@ -436,7 +436,7 @@
 const Type
 Function::GetArgumentTypeAtIndex (size_t idx)
 {
-    clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetOpaqueClangQualType()));
+    clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangType()));
    assert (clang_type->isFunctionType());
    if (!clang_type->isFunctionProtoType())
         return Type();
@@ -465,7 +465,7 @@
 const char *
 Function::GetArgumentNameAtIndex (size_t idx)
 {
-   clang::Type *clang_type = static_cast<clang::QualType *>(GetType()->GetOpaqueClangQualType())->getTypePtr();
+   clang::Type *clang_type = static_cast<clang::QualType *>(GetType()->GetClangType())->getTypePtr();
    assert (clang_type->isFunctionType());
    if (!clang_type->isFunctionProtoType())
        return NULL;
@@ -475,7 +475,7 @@
 bool
 Function::IsVariadic ()
 {
-   const clang::Type *clang_type = static_cast<clang::QualType *>(GetType()->GetOpaqueClangQualType())->getTypePtr();
+   const clang::Type *clang_type = static_cast<clang::QualType *>(GetType()->GetClangType())->getTypePtr();
    assert (clang_type->isFunctionType());
    if (!clang_type->isFunctionProtoType())
         return false;
diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
index 4a5e4e1..a4f0410 100644
--- a/source/Symbol/Type.cpp
+++ b/source/Symbol/Type.cpp
@@ -26,6 +26,8 @@
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 
+using namespace lldb;
+
 lldb_private::Type::Type
 (
     lldb::user_id_t uid,
@@ -36,7 +38,7 @@
     lldb::user_id_t encoding_uid,
     EncodingUIDType encoding_uid_type,
     const Declaration& decl,
-    void *clang_type
+    clang_type_t clang_type
 ) :
     UserID (uid),
     m_name (name),
@@ -176,7 +178,7 @@
 {
     if (!(m_name))
     {
-        if (ResolveClangType())
+        if (ResolveClangType(true))
         {
             std::string type_name = ClangASTContext::GetTypeName (m_clang_qual_type);
             if (!type_name.empty())
@@ -206,7 +208,7 @@
     lldb::Format format
 )
 {
-    if (ResolveClangType())
+    if (ResolveClangType(true))
     {
         if (show_types)
         {
@@ -254,7 +256,7 @@
             }
             if (m_byte_size == 0)
             {
-                uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetOpaqueClangQualType());
+                uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangType());
                 m_byte_size = (bit_width + 7 ) / 8;
             }
             break;
@@ -396,7 +398,7 @@
 }
 
 bool
-lldb_private::Type::ResolveClangType()
+lldb_private::Type::ResolveClangType (bool forward_decl_is_ok)
 {
     if (m_clang_qual_type == NULL)
     {
@@ -410,38 +412,38 @@
                 switch (m_encoding_uid_type)
                 {
                 case eIsTypeWithUID:
-                    m_clang_qual_type = encoding_type->GetOpaqueClangQualType();
+                    m_clang_qual_type = encoding_type->GetClangType();
                     break;
 
                 case eIsConstTypeWithUID:
-                    m_clang_qual_type = ClangASTContext::AddConstModifier (encoding_type->GetOpaqueClangQualType());
+                    m_clang_qual_type = ClangASTContext::AddConstModifier (encoding_type->GetClangType(forward_decl_is_ok));
                     break;
 
                 case eIsRestrictTypeWithUID:
-                    m_clang_qual_type = ClangASTContext::AddRestrictModifier (encoding_type->GetOpaqueClangQualType());
+                    m_clang_qual_type = ClangASTContext::AddRestrictModifier (encoding_type->GetClangType(forward_decl_is_ok));
                     break;
 
                 case eIsVolatileTypeWithUID:
-                    m_clang_qual_type = ClangASTContext::AddVolatileModifier (encoding_type->GetOpaqueClangQualType());
+                    m_clang_qual_type = ClangASTContext::AddVolatileModifier (encoding_type->GetClangType(forward_decl_is_ok));
                     break;
 
                 case eTypedefToTypeWithUID:
-                    m_clang_qual_type = type_list->CreateClangTypedefType (this, encoding_type);
+                    m_clang_qual_type = type_list->CreateClangTypedefType (this, encoding_type, forward_decl_is_ok);
                     // Clear the name so it can get fully qualified in case the
                     // typedef is in a namespace.
                     m_name.Clear();
                     break;
 
                 case ePointerToTypeWithUID:
-                    m_clang_qual_type = type_list->CreateClangPointerType (encoding_type);
+                    m_clang_qual_type = type_list->CreateClangPointerType (encoding_type, forward_decl_is_ok);
                     break;
 
                 case eLValueReferenceToTypeWithUID:
-                    m_clang_qual_type = type_list->CreateClangLValueReferenceType (encoding_type);
+                    m_clang_qual_type = type_list->CreateClangLValueReferenceType (encoding_type, forward_decl_is_ok);
                     break;
 
                 case eRValueReferenceToTypeWithUID:
-                    m_clang_qual_type = type_list->CreateClangRValueReferenceType (encoding_type);
+                    m_clang_qual_type = type_list->CreateClangRValueReferenceType (encoding_type, forward_decl_is_ok);
                     break;
 
                 default:
@@ -449,11 +451,14 @@
                     break;
                 }
             }
+            // Return here since we won't need to check if this is a forward 
+            // declaration below since we already obeyed this above.
+            return m_clang_qual_type != NULL;
         }
         else
         {
             // We have no encoding type, return void?
-            void *void_clang_type = type_list->GetClangASTContext().GetBuiltInType_void();
+            clang_type_t void_clang_type = type_list->GetClangASTContext().GetBuiltInType_void();
             switch (m_encoding_uid_type)
             {
             case eIsTypeWithUID:
@@ -494,10 +499,18 @@
             }
         }
     }
+    
+    // Check if we have a forward reference to a class/struct/union/enum?
+    if (!forward_decl_is_ok && !ClangASTType::IsDefined (m_clang_qual_type))
+    {
+        // We have a forward declaration, we need to resolve it to a complete
+        // definition.
+        m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_qual_type);
+    }
     return m_clang_qual_type != NULL;
 }
 
-void *
+clang_type_t 
 lldb_private::Type::GetChildClangTypeAtIndex
 (
     const char *parent_name,
@@ -515,7 +528,7 @@
         return NULL;
 
     std::string name_str;
-    void *child_qual_type = GetClangASTContext().GetChildClangTypeAtIndex (
+    clang_type_t child_qual_type = GetClangASTContext().GetChildClangTypeAtIndex (
             parent_name,
             m_clang_qual_type,
             idx,
@@ -539,10 +552,10 @@
 
 
 
-void *
-lldb_private::Type::GetOpaqueClangQualType ()
+clang_type_t 
+lldb_private::Type::GetClangType (bool forward_decl_is_ok)
 {
-    ResolveClangType();
+    ResolveClangType(forward_decl_is_ok);
     return m_clang_qual_type;
 }
 
diff --git a/source/Symbol/TypeList.cpp b/source/Symbol/TypeList.cpp
index 4595a9f..f4bcfdf 100644
--- a/source/Symbol/TypeList.cpp
+++ b/source/Symbol/TypeList.cpp
@@ -208,31 +208,31 @@
 }
 
 void *
-TypeList::CreateClangPointerType (Type *type)
+TypeList::CreateClangPointerType (Type *type, bool forward_decl_is_ok)
 {
     assert(type);
-    return m_ast.CreatePointerType(type->GetOpaqueClangQualType());
+    return m_ast.CreatePointerType(type->GetClangType(forward_decl_is_ok));
 }
 
 void *
-TypeList::CreateClangTypedefType (Type *typedef_type, Type *base_type)
+TypeList::CreateClangTypedefType (Type *typedef_type, Type *base_type, bool forward_decl_is_ok)
 {
     assert(typedef_type && base_type);
-    return m_ast.CreateTypedefType(typedef_type->GetName().AsCString(), base_type->GetOpaqueClangQualType(), typedef_type->GetSymbolFile()->GetClangDeclContextForTypeUID(typedef_type->GetID()));
+    return m_ast.CreateTypedefType(typedef_type->GetName().AsCString(), base_type->GetClangType(forward_decl_is_ok), typedef_type->GetSymbolFile()->GetClangDeclContextForTypeUID(typedef_type->GetID()));
 }
 
 void *
-TypeList::CreateClangLValueReferenceType (Type *type)
+TypeList::CreateClangLValueReferenceType (Type *type, bool forward_decl_is_ok)
 {
     assert(type);
-    return m_ast.CreateLValueReferenceType(type->GetOpaqueClangQualType());
+    return m_ast.CreateLValueReferenceType(type->GetClangType(forward_decl_is_ok));
 }
 
 void *
-TypeList::CreateClangRValueReferenceType (Type *type)
+TypeList::CreateClangRValueReferenceType (Type *type, bool forward_decl_is_ok)
 {
     assert(type);
-    return m_ast.CreateRValueReferenceType (type->GetOpaqueClangQualType());
+    return m_ast.CreateRValueReferenceType (type->GetClangType(forward_decl_is_ok));
 }