Author: bonefish Date: 2009-10-05 05:12:16 +0200 (Mon, 05 Oct 2009) New Revision: 33434 Changeset: http://dev.haiku-os.org/changeset/33434/haiku Modified: haiku/trunk/src/apps/debugger/Jobs.cpp haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h haiku/trunk/src/apps/debugger/debug_info/NoOpStackFrameDebugInfo.cpp haiku/trunk/src/apps/debugger/debug_info/NoOpStackFrameDebugInfo.h haiku/trunk/src/apps/debugger/debug_info/StackFrameDebugInfo.h haiku/trunk/src/apps/debugger/gui/team_window/VariablesView.cpp haiku/trunk/src/apps/debugger/model/Type.cpp haiku/trunk/src/apps/debugger/model/Type.h haiku/trunk/src/apps/debugger/model/TypeComponentPath.cpp haiku/trunk/src/apps/debugger/model/TypeComponentPath.h haiku/trunk/src/apps/debugger/types/ArrayIndexPath.cpp haiku/trunk/src/apps/debugger/types/ArrayIndexPath.h Log: * ArrayIndexPath::SetTo(): Changed return type from bool to status_t. * Finished support for retrieving and displaying array element values. * Added work-around for pointer types, if the base type isn't specified in the debug info (as it should per specification). * Added support for unspecified types, function types, and pointer to member types. All types relevant for C++ should be supported now. There are still quite a few TODOs, though. Modified: haiku/trunk/src/apps/debugger/Jobs.cpp =================================================================== --- haiku/trunk/src/apps/debugger/Jobs.cpp 2009-10-05 03:11:41 UTC (rev 33433) +++ haiku/trunk/src/apps/debugger/Jobs.cpp 2009-10-05 03:12:16 UTC (rev 33434) @@ -546,7 +546,8 @@ type = dynamic_cast<TypedefType*>(type)->BaseType(); break; case TYPE_ADDRESS: - TRACE_LOCALS(" TYPE_ADDRESS\n"); + case TYPE_POINTER_TO_MEMBER: + TRACE_LOCALS(" TYPE_ADDRESS/TYPE_POINTER_TO_MEMBER\n"); if (fArchitecture->AddressSize() == 4) { valueType = B_UINT32_TYPE; TRACE_LOCALS(" -> 32 bit\n"); @@ -595,9 +596,16 @@ shortValueIsFine = true; break; } - default: - TRACE_LOCALS(" default -> unsupported\n"); + case TYPE_SUBRANGE: + TRACE_LOCALS(" TYPE_SUBRANGE -> unsupported\n"); return B_UNSUPPORTED; + case TYPE_UNSPECIFIED: + // Can't get the value for an unspecified type! + return B_BAD_VALUE; + case TYPE_FUNCTION: + TRACE_LOCALS(" TYPE_FUNCTION\n"); + // Can't get the value for a function type! + return B_BAD_VALUE; } } @@ -833,9 +841,15 @@ switch (component.typeKind) { case TYPE_PRIMITIVE: case TYPE_ENUMERATION: + case TYPE_SUBRANGE: + case TYPE_UNSPECIFIED: + case TYPE_FUNCTION: + case TYPE_POINTER_TO_MEMBER: // cannot happen TRACE_LOCALS("GetStackFrameValueJob::_ResolveTypeAndLocation(): " - "TYPE_PRIMITIVE/TYPE_ENUMERATION subcomponent!\n"); + "TYPE_PRIMITIVE/TYPE_ENUMERATION/TYPE_SUBRANGE/" + "TYPE_UNSPECIFIED/TYPE_FUNCTION/TYPE_POINTER_TO_MEMBER " + "subcomponent!\n"); return B_BAD_VALUE; case TYPE_COMPOUND: { @@ -921,8 +935,9 @@ fStackFrame, type, parentValue.ToUInt64(), location); if (error != B_OK) { TRACE_LOCALS("GetStackFrameValueJob::" - "_ResolveTypeAndLocation(): TYPE_ADDRESS: " - "ResolveObjectDataLocation() failed: %s\n", + "_ResolveTypeAndLocation(): " + "TYPE_ADDRESS/TYPE_POINTER_TO_MEMBER: " + "ResolveObjectDataLocation() failed: %s\n", strerror(error)); return error; } @@ -935,10 +950,44 @@ return B_OK; } case TYPE_ARRAY: - // TODO:... - default: - return B_UNSUPPORTED; + { + ArrayType* arrayType = dynamic_cast<ArrayType*>(parentType); + + if (component.componentKind != TYPE_COMPONENT_ARRAY_ELEMENT) + return B_UNSUPPORTED; + + // get the index path + ArrayIndexPath indexPath; + error = indexPath.SetTo(component.name.String()); + if (error != B_OK) + return error; + + if (indexPath.CountIndices() != arrayType->CountDimensions()) + return B_UNSUPPORTED; + + // resolve the element location + ValueLocation* location; + error = fStackFrame->DebugInfo()->ResolveArrayElementLocation( + fStackFrame, arrayType, indexPath, *parentLocation, location); + if (error != B_OK) { + TRACE_LOCALS("GetStackFrameValueJob::" + "_ResolveTypeAndLocation(): TYPE_ARRAY: " + "ResolveArrayElementLocation() failed: %s\n", + strerror(error)); + return error; + } + + arrayType->BaseType()->AcquireReference(); + _type = arrayType->BaseType(); + _location = location; + _valueResolved = false; + + return B_OK; + } } + + // Can never get here. + return B_UNSUPPORTED; } Modified: haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp =================================================================== --- haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp 2009-10-05 03:11:41 UTC (rev 33433) +++ haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp 2009-10-05 03:12:16 UTC (rev 33434) @@ -11,6 +11,7 @@ #include <Variant.h> +#include "ArrayIndexPath.h" #include "Architecture.h" #include "CompilationUnit.h" #include "DebugInfoEntries.h" @@ -44,6 +45,18 @@ }; +// #pragma mark - HasReturnTypePredicate + + +template<typename EntryType> +struct HasReturnTypePredicate { + inline bool operator()(EntryType* entry) const + { + return entry->ReturnType() != NULL; + } +}; + + // #pragma mark - HasEnumeratorsPredicate @@ -88,6 +101,18 @@ }; +// #pragma mark - HasParametersPredicate + + +template<typename EntryType> +struct HasParametersPredicate { + inline bool operator()(EntryType* entry) const + { + return !entry->Parameters().IsEmpty(); + } +}; + + // #pragma mark - HasLowerBoundPredicate @@ -121,6 +146,41 @@ }; +// #pragma mark - HasBitStridePredicate + + +template<typename EntryType> +struct HasBitStridePredicate { + inline bool operator()(EntryType* entry) const + { + return entry->BitStride()->IsValid(); + } +}; + + +// #pragma mark - HasByteStridePredicate + + +template<typename EntryType> +struct HasByteStridePredicate { + inline bool operator()(EntryType* entry) const + { + return entry->ByteStride()->IsValid(); + } +}; + + +// #pragma mark - HasContainingTypePredicate + + +struct HasContainingTypePredicate { + inline bool operator()(DIEPointerToMemberType* entry) const + { + return entry->ContainingType() != NULL; + } +}; + + } // unnamed namespace @@ -390,12 +450,60 @@ return fType; } + DwarfType* GetDwarfType() const + { + return fType; + } + private: DwarfType* fType; }; +// #pragma mark - DwarfFunctionParameter + + +struct DwarfStackFrameDebugInfo::DwarfFunctionParameter : FunctionParameter { +public: + DwarfFunctionParameter(DIEFormalParameter* entry, const BString& name, + DwarfType* type) + : + fEntry(entry), + fName(name), + fType(type) + { + fType->AcquireReference(); + } + + ~DwarfFunctionParameter() + { + fType->ReleaseReference(); + } + + virtual const char* Name() const + { + return fName.Length() > 0 ? fName.String() : NULL; + } + + virtual Type* GetType() const + { + return fType; + } + + DIEFormalParameter* Entry() const + { + return fEntry; + } + +private: + DIEFormalParameter* fEntry; + BString fName; + DwarfType* fType; + +}; + + // #pragma mark - DwarfPrimitiveType @@ -814,6 +922,11 @@ return fDimensions.ItemAt(index); } + DwarfArrayDimension* DwarfDimensionAt(int32 index) const + { + return fDimensions.ItemAt(index); + } + virtual DIEType* GetDIEType() const { return fEntry; @@ -843,6 +956,177 @@ }; +// #pragma mark - DwarfUnspecifiedType + + +struct DwarfStackFrameDebugInfo::DwarfUnspecifiedType : UnspecifiedType, + DwarfType { +public: + // NOTE: The entry may be NULL. + DwarfUnspecifiedType(const BString& name, DIEUnspecifiedType* entry) + : + DwarfType(name), + fEntry(entry) + { + } + + ~DwarfUnspecifiedType() + { + } + + virtual DIEType* GetDIEType() const + { + return fEntry; + } + + DIEUnspecifiedType* Entry() const + { + return fEntry; + } + +private: + DIEUnspecifiedType* fEntry; +}; + + +// #pragma mark - DwarfFunctionType + + +struct DwarfStackFrameDebugInfo::DwarfFunctionType : FunctionType, DwarfType { + DwarfFunctionType(const BString& name, DIESubroutineType* entry, + DwarfType* returnType) + : + DwarfType(name), + fEntry(entry), + fReturnType(returnType), + fHasVariableArguments(false) + { + if (fReturnType != NULL) + fReturnType->AcquireReference(); + } + + ~DwarfFunctionType() + { + for (int32 i = 0; + DwarfFunctionParameter* parameter = fParameters.ItemAt(i); i++) { + parameter->ReleaseReference(); + } + + if (fReturnType != NULL) + fReturnType->ReleaseReference(); + } + + virtual Type* ReturnType() const + { + return fReturnType; + } + + virtual int32 CountParameters() const + { + return fParameters.CountItems(); + } + + virtual FunctionParameter* ParameterAt(int32 index) const + { + return fParameters.ItemAt(index); + } + + DwarfFunctionParameter* DwarfParameterAt(int32 index) const + { + return fParameters.ItemAt(index); + } + + virtual bool HasVariableArguments() const + { + return fHasVariableArguments; + } + + void SetHasVariableArguments(bool hasVarArgs) + { + fHasVariableArguments = hasVarArgs; + } + + virtual DIEType* GetDIEType() const + { + return fEntry; + } + + DIESubroutineType* Entry() const + { + return fEntry; + } + + bool AddParameter(DwarfFunctionParameter* parameter) + { + if (!fParameters.AddItem(parameter)) + return false; + + parameter->AcquireReference(); + return true; + } + +private: + typedef BObjectList<DwarfFunctionParameter> ParameterList; + +private: + DIESubroutineType* fEntry; + DwarfType* fReturnType; + ParameterList fParameters; + bool fHasVariableArguments; +}; + + +// #pragma mark - DwarfPointerToMemberType + + +struct DwarfStackFrameDebugInfo::DwarfPointerToMemberType : PointerToMemberType, + DwarfType { +public: + DwarfPointerToMemberType(const BString& name, DIEPointerToMemberType* entry, + DwarfCompoundType* containingType, DwarfType* baseType) + : + DwarfType(name), + fEntry(entry), + fContainingType(containingType), + fBaseType(baseType) + { + fContainingType->AcquireReference(); + fBaseType->AcquireReference(); + } + + ~DwarfPointerToMemberType() + { + fContainingType->ReleaseReference(); + fBaseType->ReleaseReference(); + } + + virtual CompoundType* ContainingType() const + { + return fContainingType; + } + + virtual Type* BaseType() const + { + return fBaseType; + } + + virtual DIEType* GetDIEType() const + { + return fEntry; + } + + DIEPointerToMemberType* Entry() const + { + return fEntry; + } + +private: + DIEPointerToMemberType* fEntry; + DwarfCompoundType* fContainingType; + DwarfType* fBaseType; +}; + + // #pragma mark - DwarfTypeHashDefinition @@ -1064,6 +1348,158 @@ status_t +DwarfStackFrameDebugInfo::ResolveArrayElementLocation(StackFrame* stackFrame, + ArrayType* _type, const ArrayIndexPath& indexPath, + const ValueLocation& parentLocation, ValueLocation*& _location) +{ + DwarfArrayType* type = dynamic_cast<DwarfArrayType*>(_type); + if (type == NULL || indexPath.CountIndices() != type->CountDimensions()) + return B_BAD_VALUE; + DIEArrayType* typeEntry = type->Entry(); + + // If the array entry has a bit stride, get it. Otherwise fall back to the + // element type size. + int64 bitStride; + if (DIEArrayType* bitStrideOwnerEntry = DwarfUtils::GetDIEByPredicate( + typeEntry, HasBitStridePredicate<DIEArrayType>())) { + BVariant value; + status_t error = fFile->EvaluateDynamicValue(fCompilationUnit, + fSubprogramEntry, bitStrideOwnerEntry->BitStride(), + fTargetInterface, fInstructionPointer, fFramePointer, value); + if (error != B_OK) + return error; + if (!value.IsInteger()) + return B_BAD_VALUE; + bitStride = value.ToInt64(); + } else + bitStride = type->BaseType()->ByteSize() * 8; + + // Iterate backward through the dimensions and compute the total offset of + // the element. + int64 elementOffset = 0; + DwarfArrayDimension* previousDimension = NULL; + int64 previousDimensionStride = 0; + for (int32 dimensionIndex = type->CountDimensions() - 1; + dimensionIndex >= 0; dimensionIndex--) { + DwarfArrayDimension* dimension = type->DwarfDimensionAt(dimensionIndex); + int64 index = indexPath.IndexAt(dimensionIndex); + + // If the dimension has a special bit/byte stride, get it. + int64 dimensionStride = 0; + DwarfType* dimensionType = dimension->GetDwarfType(); + DIEArrayIndexType* dimensionTypeEntry = dimensionType != NULL + ? dynamic_cast<DIEArrayIndexType*>(dimensionType->GetDIEType()) + : NULL; + if (dimensionTypeEntry != NULL) { + DIEArrayIndexType* bitStrideOwnerEntry + = DwarfUtils::GetDIEByPredicate(dimensionTypeEntry, + HasBitStridePredicate<DIEArrayIndexType>()); + if (bitStrideOwnerEntry != NULL) { + BVariant value; + status_t error = fFile->EvaluateDynamicValue(fCompilationUnit, + fSubprogramEntry, bitStrideOwnerEntry->BitStride(), + fTargetInterface, fInstructionPointer, fFramePointer, + value); + if (error != B_OK) + return error; + if (!value.IsInteger()) + return B_BAD_VALUE; + dimensionStride = value.ToInt64(); + } else { + DIEArrayIndexType* byteStrideOwnerEntry + = DwarfUtils::GetDIEByPredicate(dimensionTypeEntry, + HasByteStridePredicate<DIEArrayIndexType>()); + if (byteStrideOwnerEntry != NULL) { + BVariant value; + status_t error = fFile->EvaluateDynamicValue( + fCompilationUnit, fSubprogramEntry, + byteStrideOwnerEntry->ByteStride(), fTargetInterface, + fInstructionPointer, fFramePointer, value); + if (error != B_OK) + return error; + if (!value.IsInteger()) + return B_BAD_VALUE; + dimensionStride = value.ToInt64() * 8; + } + } + } + + // If we don't have a stride for the dimension yet, use the stride of + // the previous dimension multiplied by the size of the dimension. + if (dimensionStride == 0) { + if (previousDimension != NULL) { + dimensionStride = previousDimensionStride + * previousDimension->CountElements(); + } else { + // the last dimension -- use the element bit stride + dimensionStride = bitStride; + } + } + + // If the dimension stride is still 0 (that can happen, if the dimension + // doesn't have a stride and the previous dimension's element count is + // not known), we can only resolve the first element. + if (dimensionStride == 0 && index != 0) { + WARNING("No dimension bit stride for dimension %ld and element " + "index is not 0.\n", dimensionIndex); + return B_BAD_VALUE; + } + + elementOffset += dimensionStride * index; + + previousDimension = dimension; + previousDimensionStride = dimensionStride; + } + + TRACE_LOCALS("total element bit offset: %lld\n", elementOffset); + + // create the value location object for the element + ValueLocation* location = new(std::nothrow) ValueLocation( + parentLocation.IsBigEndian()); + if (location == NULL) + return B_NO_MEMORY; + Reference<ValueLocation> locationReference(location, true); + + // If we have a single memory piece location for the array, we compute the + // element's location by hand -- not uncommonly the array size isn't known. + if (parentLocation.CountPieces() == 1) { + ValuePieceLocation piece = parentLocation.PieceAt(0); + if (piece.type == VALUE_PIECE_LOCATION_MEMORY) { + int64 byteOffset = elementOffset >= 0 + ? elementOffset / 8 : (elementOffset - 7) / 8; + piece.SetToMemory(piece.address + byteOffset); + piece.SetSize(type->BaseType()->ByteSize() * 8); + // TODO: Support bit offsets correctly! + // TODO: Support bit fields (primitive types) correctly! + + if (!location->AddPiece(piece)) + return B_NO_MEMORY; + + _location = locationReference.Detach(); + return B_OK; + } + } + + // We can't deal with negative element offsets at this point. It doesn't + // make a lot of sense anyway, if the array location consists of multiple + // pieces or lives in a register. + if (elementOffset < 0) { + WARNING("Negative element offset unsupported for multiple location " + "pieces or register pieces.\n"); + return B_UNSUPPORTED; + } + + if (!location->SetTo(parentLocation, elementOffset, + type->BaseType()->ByteSize() * 8)) { + return B_NO_MEMORY; + } + + _location = locationReference.Detach(); + return B_OK; +} + + +status_t DwarfStackFrameDebugInfo::CreateType(DIEType* typeEntry, Type*& _type) { DwarfType* type; @@ -1303,10 +1739,16 @@ dynamic_cast<DIESubrangeType*>(typeEntry), _type); case DW_TAG_unspecified_type: + return _CreateUnspecifiedType(name, + dynamic_cast<DIEUnspecifiedType*>(typeEntry), _type); + case DW_TAG_subroutine_type: + return _CreateFunctionType(name, + dynamic_cast<DIESubroutineType*>(typeEntry), _type); + case DW_TAG_ptr_to_member_type: - // TODO: Implement! - return B_UNSUPPORTED; + return _CreatePointerToMemberType(name, + dynamic_cast<DIEPointerToMemberType*>(typeEntry), _type); case DW_TAG_string_type: case DW_TAG_file_type: @@ -1523,14 +1965,24 @@ // get the base type entry DIEAddressingType* baseTypeOwnerEntry = DwarfUtils::GetDIEByPredicate( typeEntry, HasTypePredicate<DIEAddressingType>()); - if (baseTypeOwnerEntry == NULL) - return B_BAD_VALUE; // create the base type DwarfType* baseType; - status_t error = _CreateType(baseTypeOwnerEntry->GetType(), baseType); - if (error != B_OK) - return error; + if (baseTypeOwnerEntry != NULL) { + status_t error = _CreateType(baseTypeOwnerEntry->GetType(), baseType); + if (error != B_OK) + return error; + } else { + // According to the DWARF 3 specs a modified type *has* a base type. + // GCC 4 doesn't (always?) bother to add one for "void". + // TODO: We should probably search for a respective type by name. ATM + // we just create a DwarfUnspecifiedType without DIE. + TRACE_LOCALS("no base type for address type entry -- creating " + "unspecified type\n"); + baseType = new(std::nothrow) DwarfUnspecifiedType("void", NULL); + if (baseType == NULL) + return B_NO_MEMORY; + } Reference<Type> baseTypeReference(baseType, true); DwarfAddressType* type = new(std::nothrow) DwarfAddressType(name, typeEntry, @@ -1867,9 +2319,9 @@ } if (isSigned) - upperBound.SetTo(lowerBound.ToInt64() + count.ToInt64()); + upperBound.SetTo(lowerBound.ToInt64() + count.ToInt64() - 1); else - upperBound.SetTo(lowerBound.ToUInt64() + count.ToUInt64()); + upperBound.SetTo(lowerBound.ToUInt64() + count.ToUInt64() - 1); } } @@ -1903,6 +2355,144 @@ status_t +DwarfStackFrameDebugInfo::_CreateUnspecifiedType(const BString& name, + DIEUnspecifiedType* typeEntry, DwarfType*& _type) +{ + DwarfUnspecifiedType* type = new(std::nothrow) DwarfUnspecifiedType(name, + typeEntry); + if (type == NULL) + return B_NO_MEMORY; + + _type = type; + return B_OK; +} + +status_t +DwarfStackFrameDebugInfo::_CreateFunctionType(const BString& name, + DIESubroutineType* typeEntry, DwarfType*& _type) +{ + // get the return type + DIESubroutineType* returnTypeOwnerEntry = DwarfUtils::GetDIEByPredicate( + typeEntry, HasReturnTypePredicate<DIESubroutineType>()); + + // create the base type + DwarfType* returnType = NULL; + if (returnTypeOwnerEntry != NULL) { + status_t error = _CreateType(returnTypeOwnerEntry->ReturnType(), + returnType); + if (error != B_OK) + return error; + } + Reference<Type> returnTypeReference(returnType, true); + + DwarfFunctionType* type = new(std::nothrow) DwarfFunctionType(name, + typeEntry, returnType); + if (type == NULL) + return B_NO_MEMORY; + Reference<DwarfType> typeReference(type, true); + + // get the parameters + DIESubroutineType* parameterOwnerEntry = DwarfUtils::GetDIEByPredicate( + typeEntry, HasParametersPredicate<DIESubroutineType>()); + + if (parameterOwnerEntry != NULL) { + for (DebugInfoEntryList::ConstIterator it + = parameterOwnerEntry->Parameters().GetIterator(); + DebugInfoEntry* _parameterEntry = it.Next();) { + if (_parameterEntry->Tag() == DW_TAG_unspecified_parameters) { + type->SetHasVariableArguments(true); + continue; + } + + DIEFormalParameter* parameterEntry + = dynamic_cast<DIEFormalParameter*>(_parameterEntry); + + // get the type + DIEFormalParameter* typeOwnerEntry = DwarfUtils::GetDIEByPredicate( + parameterEntry, HasTypePredicate<DIEFormalParameter>()); + if (typeOwnerEntry == NULL) + return B_BAD_VALUE; + + DwarfType* parameterType; + status_t error = _CreateType(typeOwnerEntry->GetType(), + parameterType); + if (error != B_OK) + return error; + Reference<DwarfType> parameterTypeReference(parameterType, true); + + // get the name + BString parameterName; + DwarfUtils::GetDIEName(parameterEntry, parameterName); + + // create and add the parameter object + DwarfFunctionParameter* parameter + = new(std::nothrow) DwarfFunctionParameter(parameterEntry, + parameterName, parameterType); + Reference<DwarfFunctionParameter> parameterReference(parameter, + true); + if (parameter == NULL || !type->AddParameter(parameter)) + return B_NO_MEMORY; + } + } + + + _type = typeReference.Detach(); + return B_OK; +} + + +status_t +DwarfStackFrameDebugInfo::_CreatePointerToMemberType(const BString& name, + DIEPointerToMemberType* typeEntry, DwarfType*& _type) +{ + // get the containing and base type entries + DIEPointerToMemberType* containingTypeOwnerEntry + = DwarfUtils::GetDIEByPredicate(typeEntry, + HasContainingTypePredicate()); + DIEPointerToMemberType* baseTypeOwnerEntry = DwarfUtils::GetDIEByPredicate( + typeEntry, HasTypePredicate<DIEPointerToMemberType>()); + + if (containingTypeOwnerEntry == NULL || baseTypeOwnerEntry == NULL) { + WARNING("Failed to get containing or base type for pointer to member " + "type \"%s\"\n", name.String()); + return B_BAD_VALUE; + } + + // create the containing type + DwarfType* containingType; + status_t error = _CreateType(containingTypeOwnerEntry->ContainingType(), + containingType); + if (error != B_OK) + return error; + Reference<Type> containingTypeReference(containingType, true); + + DwarfCompoundType* compoundContainingType + = dynamic_cast<DwarfCompoundType*>(containingType); + if (compoundContainingType == NULL) { + WARNING("Containing type for pointer to member type \"%s\" is not a " + "compound type.\n", name.String()); + return B_BAD_VALUE; + } + + // create the base type + DwarfType* baseType; + error = _CreateType(baseTypeOwnerEntry->GetType(), baseType); + if (error != B_OK) + return error; + Reference<Type> baseTypeReference(baseType, true); + + // create the type object + DwarfPointerToMemberType* type = new(std::nothrow) DwarfPointerToMemberType( + name, typeEntry, compoundContainingType, baseType); + if (type == NULL) + return B_NO_MEMORY; + + _type = type; + return B_OK; +} + + +status_t DwarfStackFrameDebugInfo::_CreateVariable(ObjectID* id, const BString& name, DIEType* typeEntry, LocationDescription* locationDescription, Variable*& _variable) @@ -2034,6 +2624,7 @@ break; case DW_TAG_pointer_type: case DW_TAG_reference_type: + case DW_TAG_ptr_to_member_type: _size = fCompilationUnit->AddressSize(); TRACE_LOCALS(" pointer/reference type: size: %llu\n", _size); Modified: haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h =================================================================== --- haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h 2009-10-05 03:11:41 UTC (rev 33433) +++ haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h 2009-10-05 03:12:16 UTC (rev 33434) @@ -22,10 +22,13 @@ class DIEEnumerationType; class DIEFormalParameter; class DIEModifiedType; +class DIEPointerToMemberType; class DIESubprogram; class DIESubrangeType; +class DIESubroutineType; class DIEType; class DIETypedef; +class DIEUnspecifiedType; class DIEVariable; class DwarfFile; class DwarfTargetInterface; @@ -65,6 +68,11 @@ DataMember* member, const ValueLocation& parentLocation, ValueLocation*& _location); + virtual status_t ResolveArrayElementLocation( + StackFrame* stackFrame, ArrayType* type, + const ArrayIndexPath& indexPath, + const ValueLocation& parentLocation, + ValueLocation*& _location); status_t CreateType(DIEType* typeEntry, Type*& _type); // returns reference @@ -85,6 +93,7 @@ struct DwarfDataMember; struct DwarfEnumerationValue; struct DwarfArrayDimension; + struct DwarfFunctionParameter; struct DwarfPrimitiveType; struct DwarfCompoundType; struct DwarfModifiedType; @@ -93,6 +102,9 @@ struct DwarfEnumerationType; struct DwarfSubrangeType; struct DwarfArrayType; + struct DwarfUnspecifiedType; + struct DwarfFunctionType; + struct DwarfPointerToMemberType; struct DwarfTypeHashDefinition; typedef BOpenHashTable<DwarfTypeHashDefinition> TypeTable; @@ -136,6 +148,15 @@ status_t _CreateSubrangeType(const BString& name, DIESubrangeType* typeEntry, DwarfType*& _type); + status_t _CreateUnspecifiedType(const BString& name, + DIEUnspecifiedType* typeEntry, + DwarfType*& _type); + status_t _CreateFunctionType(const BString& name, + DIESubroutineType* typeEntry, + DwarfType*& _type); + status_t _CreatePointerToMemberType(const BString& name, + DIEPointerToMemberType* typeEntry, + DwarfType*& _type); status_t _CreateVariable(ObjectID* id, const BString& name, DIEType* typeEntry, Modified: haiku/trunk/src/apps/debugger/debug_info/NoOpStackFrameDebugInfo.cpp =================================================================== --- haiku/trunk/src/apps/debugger/debug_info/NoOpStackFrameDebugInfo.cpp 2009-10-05 03:11:41 UTC (rev 33433) +++ haiku/trunk/src/apps/debugger/debug_info/NoOpStackFrameDebugInfo.cpp 2009-10-05 03:12:16 UTC (rev 33434) @@ -43,3 +43,12 @@ { return B_UNSUPPORTED; } + + +status_t +NoOpStackFrameDebugInfo::ResolveArrayElementLocation(StackFrame* stackFrame, + ArrayType* type, const ArrayIndexPath& indexPath, + const ValueLocation& parentLocation, ValueLocation*& _location) +{ + return B_UNSUPPORTED; +} Modified: haiku/trunk/src/apps/debugger/debug_info/NoOpStackFrameDebugInfo.h =================================================================== --- haiku/trunk/src/apps/debugger/debug_info/NoOpStackFrameDebugInfo.h 2009-10-05 03:11:41 UTC (rev 33433) +++ haiku/trunk/src/apps/debugger/debug_info/NoOpStackFrameDebugInfo.h 2009-10-05 03:12:16 UTC (rev 33434) @@ -29,6 +29,11 @@ DataMember* member, const ValueLocation& parentLocation, ValueLocation*& _location); + virtual status_t ResolveArrayElementLocation( + StackFrame* stackFrame, ArrayType* type, + const ArrayIndexPath& indexPath, + const ValueLocation& parentLocation, + ValueLocation*& _location); }; Modified: haiku/trunk/src/apps/debugger/debug_info/StackFrameDebugInfo.h =================================================================== --- haiku/trunk/src/apps/debugger/debug_info/StackFrameDebugInfo.h 2009-10-05 03:11:41 UTC (rev 33433) +++ haiku/trunk/src/apps/debugger/debug_info/StackFrameDebugInfo.h 2009-10-05 03:12:16 UTC (rev 33434) @@ -11,6 +11,8 @@ #include "Types.h" +class ArrayIndexPath; +class ArrayType; class Architecture; class BaseType; class DataMember; @@ -46,6 +48,12 @@ const ValueLocation& parentLocation, ValueLocation*& _location) = 0; // returns a reference + virtual status_t ResolveArrayElementLocation( + StackFrame* stackFrame, ArrayType* type, + const ArrayIndexPath& indexPath, + const ValueLocation& parentLocation, + ValueLocation*& _location) = 0; + // returns a reference protected: Architecture* fArchitecture; Modified: haiku/trunk/src/apps/debugger/gui/team_window/VariablesView.cpp =================================================================== --- haiku/trunk/src/apps/debugger/gui/team_window/VariablesView.cpp 2009-10-05 03:11:41 UTC (rev 33433) +++ haiku/trunk/src/apps/debugger/gui/team_window/VariablesView.cpp 2009-10-05 03:12:16 UTC (rev 33434) @@ -548,7 +548,9 @@ return; } - if (!baseIndexPath.SetTo(arrayComponent.name.String())) + status_t error + = baseIndexPath.SetTo(arrayComponent.name.String()); + if (error != B_OK) return; baseDimension = baseIndexPath.CountIndices(); @@ -579,10 +581,8 @@ component.SetToArrayElement(type->Kind(), indexPath); TypeComponentPath* elementPath - = new(std::nothrow) TypeComponentPath(*path); + = path->CreateSubPath(path->CountComponents() - 1); if (elementPath == NULL - || elementPath->CountComponents() - != path->CountComponents() || !elementPath->AddComponent(component)) { delete elementPath; return; @@ -604,10 +604,24 @@ case TYPE_ENUMERATION: TRACE_LOCALS("TYPE_ENUMERATION\n"); done = true; + break; + case TYPE_SUBRANGE: + TRACE_LOCALS("TYPE_SUBRANGE -> unsupported\n"); + // TODO: Support! return; - default: - TRACE_LOCALS("unknown\n"); + case TYPE_UNSPECIFIED: + // Should never get here -- we don't create nodes for + // unspecified types. + TRACE_LOCALS("TYPE_UNSPECIFIED\n"); return; + case TYPE_FUNCTION: + TRACE_LOCALS("TYPE_FUNCTION -> unsupported\n"); [... truncated: 318 lines follow ...]