[haiku-commits] r33434 - in haiku/trunk/src/apps/debugger: . debug_info gui/team_window model types

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 5 Oct 2009 05:12:16 +0200 (CEST)

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 ...]

Other related posts:

  • » [haiku-commits] r33434 - in haiku/trunk/src/apps/debugger: . debug_info gui/team_window model types - ingo_weinhold