diff --git a/lldb/include/lldb/Core/Error.h b/lldb/include/lldb/Core/Error.h index adaf5dbb2442..b8eb7be50d88 100644 --- a/lldb/include/lldb/Core/Error.h +++ b/lldb/include/lldb/Core/Error.h @@ -64,9 +64,12 @@ public: /// @param[in] type /// The type for \a err. //------------------------------------------------------------------ + Error (); + explicit - Error (ValueType err = 0, lldb::ErrorType type = lldb::eErrorTypeGeneric); + Error (ValueType err, lldb::ErrorType type = lldb::eErrorTypeGeneric); + Error (const Error &rhs); //------------------------------------------------------------------ /// Assignment operator. /// diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index 4fd1151e8c08..f02c0b00b36a 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -506,7 +506,10 @@ public: // Enumeration Types //------------------------------------------------------------------ lldb::clang_type_t - CreateEnumerationType (const Declaration &decl, const char *name, lldb::clang_type_t integer_qual_type); + CreateEnumerationType (const char *name, + clang::DeclContext *decl_ctx, + const Declaration &decl, + lldb::clang_type_t integer_qual_type); static lldb::clang_type_t GetEnumerationIntegerType (lldb::clang_type_t enum_clang_type); diff --git a/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig index ad9381952260..5a8a88ec4054 100644 --- a/lldb/scripts/lldb.swig +++ b/lldb/scripts/lldb.swig @@ -18,11 +18,11 @@ if (PyList_Check($input)) { int size = PyList_Size($input); int i = 0; - $1 = (char **) malloc((size+1) * sizeof(char)); + $1 = (char **) malloc((size+1) * sizeof(char*)); for (i = 0; i < size; i++) { PyObject *o = PyList_GetItem($input,i); if (PyString_Check(o)) - $1[i] = PyString_AsString(PyList_GetItem($input,i)); + $1[i] = PyString_AsString(o); else { PyErr_SetString(PyExc_TypeError,"list must contain strings"); free($1); @@ -54,6 +54,43 @@ } + +// typemap for an outgoing buffer +%typemap(in) (const void *wbuffer, size_t len) { + if (!PyString_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting a string"); + return NULL; + } + $1 = (void *) PyString_AsString($input); + $2 = PyString_Size($input); +} + +// typemap for an incoming buffer +%typemap(in) (void *rbuffer, size_t len) { + if (!PyInt_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting an integer"); + return NULL; + } + $2 = PyInt_AsLong($input); + if ($2 < 0) { + PyErr_SetString(PyExc_ValueError, "Positive integer expected"); + return NULL; + } + $1 = (void *) malloc($2); +} + +// Return the buffer. Discarding any previous return result +%typemap(argout) (void *rbuffer, size_t len) { + Py_XDECREF($result); /* Blow away any previous result */ + if (result < 0) { /* Check for I/O error */ + free($1); + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + $result = PyString_FromStringAndSize($1,result); + free($1); +} + /* The liblldb header files to be included. */ %{ diff --git a/lldb/source/Core/Error.cpp b/lldb/source/Core/Error.cpp index 104dfc6d693c..ee7d6f21cda9 100644 --- a/lldb/source/Core/Error.cpp +++ b/lldb/source/Core/Error.cpp @@ -27,6 +27,13 @@ using namespace lldb; using namespace lldb_private; +Error::Error (): + m_code (0), + m_type (eErrorTypeInvalid), + m_string () +{ +} + //---------------------------------------------------------------------- // Default constructor //---------------------------------------------------------------------- @@ -36,6 +43,14 @@ Error::Error(ValueType err, ErrorType type) : m_string () { } + +Error::Error (const Error &rhs) : + m_code (rhs.m_code), + m_type (rhs.m_type), + m_string (rhs.m_string) +{ +} + //---------------------------------------------------------------------- // Assignment operator //---------------------------------------------------------------------- diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 0125a0373e8b..c1e958e29410 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -124,40 +124,45 @@ AppleObjCRuntimeV2::SetExceptionBreakpoints () } } -struct BufStruct { - char contents[1024]; -}; - ClangUtilityFunction * AppleObjCRuntimeV2::CreateObjectChecker(const char *name) { - std::auto_ptr buf(new BufStruct); + char check_function_code[1024]; + int len = 0; if (m_has_object_getClass) { - assert(snprintf(&buf->contents[0], sizeof(buf->contents), - "extern \"C\" void *gdb_object_getClass(void *); \n" - "extern \"C\" void \n" - "%s(void *$__lldb_arg_obj) \n" - "{ \n" - " if (!gdb_object_getClass($__lldb_arg_obj)) \n" - " abort(); \n" - "} \n", - name) < sizeof(buf->contents)); + len = ::snprintf (check_function_code, + sizeof(check_function_code), + "extern \"C\" void *gdb_object_getClass(void *); \n" + "extern \"C\" void \n" + "%s(void *$__lldb_arg_obj) \n" + "{ \n" + " if ($__lldb_arg_obj == (void *)0) \n" + " return; // nil is ok \n" + " if (!gdb_object_getClass($__lldb_arg_obj)) \n" + " *((volatile int *)0) = 'ocgc'; \n" + "} \n", + name); } else { - assert(snprintf(&buf->contents[0], sizeof(buf->contents), - "extern \"C\" void *gdb_class_getClass(void *); \n" - "extern \"C\" void \n" - "%s(void *$__lldb_arg_obj) \n" - "{ \n" - " void **$isa_ptr = (void **)$__lldb_arg_obj; \n" - " if (!$isa_ptr || !gdb_class_getClass(*$isa_ptr)) \n" - " abort(); \n" - "} \n", - name) < sizeof(buf->contents)); + len = ::snprintf (check_function_code, + sizeof(check_function_code), + "extern \"C\" void *gdb_class_getClass(void *); \n" + "extern \"C\" void \n" + "%s(void *$__lldb_arg_obj) \n" + "{ \n" + " if ($__lldb_arg_obj == (void *)0) \n" + " return; // nil is ok \n" + " void **$isa_ptr = (void **)$__lldb_arg_obj; \n" + " if (!gdb_class_getClass(*$isa_ptr)) \n" + " *((volatile int *)0) = 'ocgc'; \n" + "} \n", + name); } - return new ClangUtilityFunction(buf->contents, name); + assert (len < sizeof(check_function_code)); + + return new ClangUtilityFunction(check_function_code, name); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index f40ad156a3d2..ed916cc78eab 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1300,7 +1300,21 @@ SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid) DWARFCompileUnitSP cu_sp; const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp); if (type_die != NULL) + { + // We might be coming in in the middle of a type tree (a class + // withing a class, an enum within a class), so parse any needed + // parent DIEs before we get to this one... + const DWARFDebugInfoEntry* parent_die = type_die->GetParent(); + switch (parent_die->Tag()) + { + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: + ResolveType(cu_sp.get(), parent_die); + break; + } return ResolveType (cu_sp.get(), type_die); + } } return NULL; } @@ -2651,7 +2665,9 @@ SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoE Type *type_ptr = m_die_to_type.lookup (die); if (type_ptr == NULL) { - SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu)); + CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu); + assert (lldb_cu); + SymbolContext sc(lldb_cu); type_sp = ParseType(sc, curr_cu, die, NULL); } else if (type_ptr != DIE_IS_BEING_PARSED) @@ -2698,45 +2714,89 @@ SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebu clang::DeclContext * SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) { - DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); - if (pos != m_die_to_decl_ctx.end()) - return pos->second; + if (m_clang_tu_decl == NULL) + m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl(); + //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x )\n", die->GetOffset()); + const DWARFDebugInfoEntry * const decl_die = die; while (die != NULL) { - switch (die->Tag()) + // If this is the original DIE that we are searching for a declaration + // for, then don't look in the cache as we don't want our own decl + // context to be our decl context... + if (decl_die != die) { - case DW_TAG_namespace: + DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); + if (pos != m_die_to_decl_ctx.end()) { - const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL); - if (namespace_name) - { - Declaration decl; // TODO: fill in the decl object - clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent())); - if (namespace_decl) - m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl; - return namespace_decl; - } + //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); + return pos->second; } - break; - default: - break; + //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); + + switch (die->Tag()) + { + case DW_TAG_namespace: + { + const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL); + if (namespace_name) + { + Declaration decl; // TODO: fill in the decl object + clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent())); + if (namespace_decl) + { + //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); + m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl; + } + return namespace_decl; + } + } + break; + + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: + { + ResolveType (curr_cu, die); + pos = m_die_to_decl_ctx.find(die); + assert (pos != m_die_to_decl_ctx.end()); + if (pos != m_die_to_decl_ctx.end()) + { + //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); + return pos->second; + } + } + break; + + default: + break; + } } - clang::DeclContext *decl_ctx; - decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET)); - if (decl_ctx) - return decl_ctx; - decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET)); - if (decl_ctx) - return decl_ctx; + clang::DeclContext *decl_ctx; + dw_offset_t die_offset = die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET); + if (die_offset != DW_INVALID_OFFSET) + { + //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset); + decl_ctx = GetClangDeclContextForDIEOffset (die_offset); + if (decl_ctx != m_clang_tu_decl) + return decl_ctx; + } + + die_offset = die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); + if (die_offset != DW_INVALID_OFFSET) + { + //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset); + decl_ctx = GetClangDeclContextForDIEOffset (die_offset); + if (decl_ctx != m_clang_tu_decl) + return decl_ctx; + } die = die->GetParent(); } // Right now we have only one translation unit per module... - if (m_clang_tu_decl == NULL) - m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl(); + //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset()); return m_clang_tu_decl; } @@ -3051,7 +3111,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, } - if (is_forward_declaration) + if (is_forward_declaration && die->HasChildren() == false) { // We have a forward declaration to a type and we need // to try and find a full declaration. We look in the @@ -3183,8 +3243,9 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8); - clang_type = ast.CreateEnumerationType (decl, - type_name_cstr, + clang_type = ast.CreateEnumerationType (type_name_cstr, + GetClangDeclContextForDIE (dwarf_cu, die->GetParent()), + decl, enumerator_clang_type); } else diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 19dbd887a3f4..e7e948bb802e 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -3487,7 +3487,13 @@ ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type) #pragma mark Enumeration Types clang_type_t -ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type) +ClangASTContext::CreateEnumerationType +( + const char *name, + DeclContext *decl_ctx, + const Declaration &decl, + clang_type_t integer_qual_type +) { // TODO: Do something intelligent with the Declaration object passed in // like maybe filling in the SourceLocation with it... @@ -3499,7 +3505,7 @@ ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *nam // const bool IsFixed = false; EnumDecl *enum_decl = EnumDecl::Create (*ast_context, - ast_context->getTranslationUnitDecl(), + decl_ctx, SourceLocation(), name && name[0] ? &ast_context->Idents.get(name) : NULL, SourceLocation(), diff --git a/lldb/test/foundation/main.m b/lldb/test/foundation/main.m index f787297f6d9c..6e4b1b04bf3d 100644 --- a/lldb/test/foundation/main.m +++ b/lldb/test/foundation/main.m @@ -98,6 +98,7 @@ Test_MyString (const char *program) int Test_NSArray () { + NSMutableArray *nil_mutable_array = nil; NSArray *array1 = [NSArray arrayWithObjects: @"array1 object1", @"array1 object2", @"array1 object3", nil]; NSArray *array2 = [NSArray arrayWithObjects: array1, @"array2 object2", @"array2 object3", nil]; // Expressions to test here for NSArray: @@ -105,6 +106,7 @@ Test_NSArray () // expression array1.count // expression [array2 count] // expression array2.count + // expression [nil_mutable_array count] id obj; // After each object at index call, use expression and validate object obj = [array1 objectAtIndex: 0]; @@ -114,7 +116,7 @@ Test_NSArray () obj = [array2 objectAtIndex: 0]; obj = [array2 objectAtIndex: 1]; obj = [array2 objectAtIndex: 2]; - + NSUInteger count = [nil_mutable_array count]; return 0; }