root/src/kits/debugger/debug_info/DwarfTypes.h
/*
 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
 * Copyright 2012-2013, Rene Gollent, rene@gollent.com.
 * Distributed under the terms of the MIT License.
 */
#ifndef DWARF_TYPES_H
#define DWARF_TYPES_H


#include <String.h>

#include <ObjectList.h>
#include <Referenceable.h>

#include "Type.h"


class Architecture;
class CompilationUnit;
class DebugInfoEntry;
class DIEAddressingType;
class DIEArrayType;
class DIEBaseType;
class DIECompoundType;
class DIEEnumerationType;
class DIEEnumerator;
class DIEFormalParameter;
class DIEInheritance;
class DIEMember;
class DIEModifiedType;
class DIEPointerToMemberType;
class DIESubprogram;
class DIESubrangeType;
class DIESubroutineType;
class DIEType;
class DIETypedef;
class DIEUnspecifiedType;
class DwarfFile;
class DwarfTargetInterface;
struct LocationDescription;
struct MemberLocation;
class RegisterMap;
class ValueLocation;


// conversion functions between model types and dwarf types
type_kind dwarf_tag_to_type_kind(int32 tag);
int32 dwarf_tag_to_subtype_kind(int32 tag);


class DwarfTypeContext : public BReferenceable {
public:
                                                                DwarfTypeContext(Architecture* architecture,
                                                                        image_id imageID, DwarfFile* file,
                                                                        CompilationUnit* compilationUnit,
                                                                        DIESubprogram* subprogramEntry,
                                                                        target_addr_t instructionPointer,
                                                                        target_addr_t framePointer,
                                                                        target_addr_t relocationDelta,
                                                                        DwarfTargetInterface* targetInterface,
                                                                        RegisterMap* fromDwarfRegisterMap);
                                                                ~DwarfTypeContext();

                        Architecture*           GetArchitecture() const
                                                                        { return fArchitecture; }
                        image_id                        ImageID() const
                                                                        { return fImageID; }
                        DwarfFile*                      File() const
                                                                        { return fFile; }
                        CompilationUnit*        GetCompilationUnit() const
                                                                        { return fCompilationUnit; }
                        DIESubprogram*          SubprogramEntry() const
                                                                        { return fSubprogramEntry; }
                        target_addr_t           InstructionPointer() const
                                                                        { return fInstructionPointer; }
                        target_addr_t           FramePointer() const
                                                                        { return fFramePointer; }
                        target_addr_t           RelocationDelta() const
                                                                        { return fRelocationDelta; }
                        DwarfTargetInterface* TargetInterface() const
                                                                        { return fTargetInterface; }
                        RegisterMap*            FromDwarfRegisterMap() const
                                                                        { return fFromDwarfRegisterMap; }
                        uint8                   AddressSize() const;
                        bool                    IsBigEndian() const;

private:
                        Architecture*           fArchitecture;
                        image_id                        fImageID;
                        DwarfFile*                      fFile;
                        CompilationUnit*        fCompilationUnit;
                        DIESubprogram*          fSubprogramEntry;
                        target_addr_t           fInstructionPointer;
                        target_addr_t           fFramePointer;
                        target_addr_t           fRelocationDelta;
                        DwarfTargetInterface* fTargetInterface;
                        RegisterMap*            fFromDwarfRegisterMap;
};


class DwarfType : public virtual Type {
public:
                                                                DwarfType(DwarfTypeContext* typeContext,
                                                                        const BString& name, const DIEType* entry);
                                                                ~DwarfType();

        static  bool                            GetTypeID(const DIEType* entry, BString& _id);

        virtual image_id                        ImageID() const;
        virtual const BString&          ID() const;
        virtual const BString&          Name() const;
        virtual target_size_t           ByteSize() const;

        virtual status_t                        CreateDerivedAddressType(
                                                                        address_type_kind kind,
                                                                        AddressType*& _resultType);

        virtual status_t                        CreateDerivedArrayType(
                                                                        int64 lowerBound,
                                                                        int64 elementCount,
                                                                        bool extendExisting,
                                                                        ArrayType*& _resultType);

        virtual status_t                        ResolveObjectDataLocation(
                                                                        const ValueLocation& objectLocation,
                                                                        ValueLocation*& _location);
        virtual status_t                        ResolveObjectDataLocation(
                                                                        target_addr_t objectAddress,
                                                                        ValueLocation*& _location);

                        DwarfTypeContext*       TypeContext() const
                                                                        { return fTypeContext; }

                        void                            SetByteSize(target_size_t size)
                                                                        { fByteSize = size; }

        virtual DIEType*                        GetDIEType() const = 0;

                        status_t                        ResolveLocation(DwarfTypeContext* typeContext,
                                                                        const LocationDescription* description,
                                                                        target_addr_t objectAddress,
                                                                        bool hasObjectAddress,
                                                                        ValueLocation& _location);

private:
                        DwarfTypeContext*       fTypeContext;
                        BString                         fName;
                        BString                         fID;
                        target_size_t           fByteSize;
};


class DwarfInheritance : public BaseType {
public:
                                                                DwarfInheritance(DIEInheritance* entry,
                                                                        DwarfType* type);
                                                                ~DwarfInheritance();

        virtual Type*                           GetType() const;

                        DwarfType*                      GetDwarfType() const
                                                                        { return fType; }
                        DIEInheritance*         Entry() const
                                                                        { return fEntry; }

private:
                        DIEInheritance*         fEntry;
                        DwarfType*                      fType;
};


class DwarfDataMember : public DataMember {
public:
                                                                DwarfDataMember(DIEMember* entry,
                                                                        const BString& name, DwarfType* type);
                                                                ~DwarfDataMember();

        virtual const char*                     Name() const;
        virtual Type*                           GetType() const;

                        DwarfType*                      GetDwarfType() const
                                                                        { return fType; }
                        DIEMember*                      Entry() const
                                                                        { return fEntry; }

private:
                        DIEMember*                      fEntry;
                        BString                         fName;
                        DwarfType*                      fType;
};


class DwarfEnumeratorValue : public EnumeratorValue {
public:
                                                                DwarfEnumeratorValue(DIEEnumerator* entry,
                                                                        const BString& name, const BVariant& value);
                                                                ~DwarfEnumeratorValue();

        virtual const char*                     Name() const;
        virtual BVariant                        Value() const;

                        DIEEnumerator*          Entry() const
                                                                        { return fEntry; }

private:
                        DIEEnumerator*          fEntry;
                        BString                         fName;
                        BVariant                        fValue;
};


class DwarfArrayDimension : public ArrayDimension {
public:
                                                                DwarfArrayDimension(DwarfType* type);
                                                                ~DwarfArrayDimension();

        virtual Type*                           GetType() const;

                        DwarfType*                      GetDwarfType() const
                                                                        { return fType; }

private:
                        DwarfType*                      fType;

};


class DwarfFunctionParameter : public FunctionParameter {
public:
                                                                DwarfFunctionParameter(
                                                                        DIEFormalParameter* entry,
                                                                        const BString& name, DwarfType* type);
                                                                ~DwarfFunctionParameter();

        virtual const char*                     Name() const;
        virtual Type*                           GetType() const;

                        DIEFormalParameter*     Entry() const
                                                                        { return fEntry; }

private:
                        DIEFormalParameter*     fEntry;
                        BString                         fName;
                        DwarfType*                      fType;

};


class DwarfTemplateParameter : public TemplateParameter {
public:
                                                                DwarfTemplateParameter(
                                                                        DebugInfoEntry* entry,
                                                                        DwarfType* type);
                                                                ~DwarfTemplateParameter();

        virtual template_type_kind      Kind() const { return fTemplateKind; }
        virtual Type*                           GetType() const { return fType; }
        virtual BVariant                        Value() const { return fValue; }

private:
                        DebugInfoEntry*         fEntry;
                        template_type_kind      fTemplateKind;
                        Type*                           fType;
                        BVariant                        fValue;
};


class DwarfPrimitiveType : public PrimitiveType, public DwarfType {
public:
                                                                DwarfPrimitiveType(
                                                                        DwarfTypeContext* typeContext,
                                                                        const BString& name, DIEBaseType* entry,
                                                                        uint32 typeConstant);

        virtual DIEType*                        GetDIEType() const;
        virtual uint32                          TypeConstant() const;

                        DIEBaseType*            Entry() const
                                                                        { return fEntry; }

private:
                        DIEBaseType*            fEntry;
                        uint32                          fTypeConstant;
};


class DwarfCompoundType : public CompoundType, public DwarfType {
public:
                                                                DwarfCompoundType(DwarfTypeContext* typeContext,
                                                                        const BString& name, DIECompoundType* entry,
                                                                        compound_type_kind compoundKind);
                                                                ~DwarfCompoundType();

        virtual compound_type_kind      CompoundKind() const;

        virtual int32                           CountBaseTypes() const;
        virtual BaseType*                       BaseTypeAt(int32 index) const;

        virtual int32                           CountDataMembers() const;
        virtual DataMember*                     DataMemberAt(int32 index) const;

        virtual int32                           CountTemplateParameters() const;
        virtual TemplateParameter*      TemplateParameterAt(int32 index) const;

        virtual status_t                        ResolveBaseTypeLocation(BaseType* _baseType,
                                                                        const ValueLocation& parentLocation,
                                                                        ValueLocation*& _location);
        virtual status_t                        ResolveDataMemberLocation(DataMember* _member,
                                                                        const ValueLocation& parentLocation,
                                                                        ValueLocation*& _location);

        virtual DIEType*                        GetDIEType() const;

                        DIECompoundType*        Entry() const
                                                                        { return fEntry; }

                        bool                            AddInheritance(DwarfInheritance* inheritance);
                        bool                            AddDataMember(DwarfDataMember* member);
                        bool                            AddTemplateParameter(
                                                                        DwarfTemplateParameter* parameter);

private:
                        typedef BObjectList<DwarfDataMember> DataMemberList;
                        typedef BObjectList<DwarfInheritance> InheritanceList;
                        typedef BObjectList<DwarfTemplateParameter> TemplateParameterList;

private:
                        status_t                        _ResolveDataMemberLocation(
                                                                        DwarfType* memberType,
                                                                        const MemberLocation* memberLocation,
                                                                        const ValueLocation& parentLocation,
                                                                        bool isBitField,
                                                                        ValueLocation*& _location);

private:
                        compound_type_kind      fCompoundKind;
                        DIECompoundType*        fEntry;
                        InheritanceList         fInheritances;
                        DataMemberList          fDataMembers;
                        TemplateParameterList fTemplateParameters;
};


class DwarfArrayType : public ArrayType, public DwarfType {
public:
                                                                DwarfArrayType(DwarfTypeContext* typeContext,
                                                                        const BString& name, DIEArrayType* entry,
                                                                        DwarfType* baseType);
                                                                ~DwarfArrayType();

        virtual Type*                           BaseType() const;

        virtual int32                           CountDimensions() const;
        virtual ArrayDimension*         DimensionAt(int32 index) const;

        virtual status_t                        ResolveElementLocation(
                                                                        const ArrayIndexPath& indexPath,
                                                                        const ValueLocation& parentLocation,
                                                                        ValueLocation*& _location);

        virtual DIEType*                        GetDIEType() const;

                        bool                            AddDimension(DwarfArrayDimension* dimension);

                        DwarfArrayDimension* DwarfDimensionAt(int32 index) const
                                                                        { return fDimensions.ItemAt(index); }
                        DIEArrayType*           Entry() const
                                                                        { return fEntry; }

private:
                        typedef BObjectList<DwarfArrayDimension> DimensionList;

private:
                        DIEArrayType*           fEntry;
                        DwarfType*                      fBaseType;
                        DimensionList           fDimensions;
};


class DwarfModifiedType : public ModifiedType, public DwarfType {
public:
                                                                DwarfModifiedType(DwarfTypeContext* typeContext,
                                                                        const BString& name, DIEModifiedType* entry,
                                                                        uint32 modifiers, DwarfType* baseType);
                                                                ~DwarfModifiedType();

        virtual uint32                          Modifiers() const;
        virtual Type*                           BaseType() const;

        virtual DIEType*                        GetDIEType() const;

                        DIEModifiedType*        Entry() const
                                                                        { return fEntry; }

private:
                        DIEModifiedType*        fEntry;
                        uint32                          fModifiers;
                        DwarfType*                      fBaseType;
};


class DwarfTypedefType : public TypedefType, public DwarfType {
public:
                                                                DwarfTypedefType(DwarfTypeContext* typeContext,
                                                                        const BString& name, DIETypedef* entry,
                                                                        DwarfType* baseType);
                                                                ~DwarfTypedefType();

        virtual Type*                           BaseType() const;

        virtual DIEType*                        GetDIEType() const;

                        DIETypedef*                     Entry() const
                                                                        { return fEntry; }

private:
                        DIETypedef*                     fEntry;
                        DwarfType*                      fBaseType;
};


class DwarfAddressType : public AddressType, public DwarfType {
public:
                                                                DwarfAddressType(DwarfTypeContext* typeContext,
                                                                        const BString& name,
                                                                        DIEAddressingType* entry,
                                                                        address_type_kind addressKind,
                                                                        DwarfType* baseType);
                                                                ~DwarfAddressType();

        virtual address_type_kind       AddressKind() const;
        virtual Type*                           BaseType() const;

        virtual DIEType*                        GetDIEType() const;

                        DIEAddressingType*      Entry() const
                                                                        { return fEntry; }

private:
                        DIEAddressingType*      fEntry;
                        address_type_kind       fAddressKind;
                        DwarfType*                      fBaseType;
};


class DwarfEnumerationType : public EnumerationType, public DwarfType {
public:
                                                                DwarfEnumerationType(
                                                                        DwarfTypeContext* typeContext,
                                                                        const BString& name,
                                                                        DIEEnumerationType* entry,
                                                                        DwarfType* baseType);
                                                                ~DwarfEnumerationType();

        virtual Type*                           BaseType() const;

        virtual int32                           CountValues() const;
        virtual EnumeratorValue*        ValueAt(int32 index) const;

        virtual DIEType*                        GetDIEType() const;

                        bool                            AddValue(DwarfEnumeratorValue* value);

                        DIEEnumerationType*     Entry() const
                                                                        { return fEntry; }

private:
                        typedef BObjectList<DwarfEnumeratorValue> ValueList;

private:
                        DIEEnumerationType*     fEntry;
                        DwarfType*                      fBaseType;
                        ValueList                       fValues;
};


class DwarfSubrangeType : public SubrangeType, public DwarfType {
public:
                                                                DwarfSubrangeType(DwarfTypeContext* typeContext,
                                                                        const BString& name, DIESubrangeType* entry,
                                                                        Type* baseType,
                                                                        const BVariant& lowerBound,
                                                                        const BVariant& upperBound);
                                                                ~DwarfSubrangeType();

        virtual Type*                           BaseType() const;

        virtual BVariant                        LowerBound() const;
        virtual BVariant                        UpperBound() const;

        virtual DIEType*                        GetDIEType() const;

                        DIESubrangeType*        Entry() const
                                                                        { return fEntry; }

private:
                        DIESubrangeType*        fEntry;
                        Type*                           fBaseType;
                        BVariant                        fLowerBound;
                        BVariant                        fUpperBound;
};


struct DwarfUnspecifiedType : public UnspecifiedType, public DwarfType {
public:
                                                                DwarfUnspecifiedType(
                                                                        DwarfTypeContext* typeContext,
                                                                        const BString& name,
                                                                        DIEUnspecifiedType* entry);
                                                                        // entry may be NULL
                                                                ~DwarfUnspecifiedType();

        virtual DIEType*                        GetDIEType() const;

                        DIEUnspecifiedType*     Entry() const
                                                                        { return fEntry; }

private:
                        DIEUnspecifiedType*     fEntry;
};


class DwarfFunctionType : public FunctionType, public DwarfType {
public:
                                                                DwarfFunctionType(DwarfTypeContext* typeContext,
                                                                        const BString& name,
                                                                        DIESubroutineType* entry,
                                                                        DwarfType* returnType);
                                                                ~DwarfFunctionType();

        virtual Type*                           ReturnType() const;

        virtual int32                           CountParameters() const;
        virtual FunctionParameter*      ParameterAt(int32 index) const;

        virtual bool                            HasVariableArguments() const;
                        void                            SetHasVariableArguments(bool hasVarArgs);

        virtual DIEType*                        GetDIEType() const;

                        bool                            AddParameter(DwarfFunctionParameter* parameter);

                        DwarfFunctionParameter* DwarfParameterAt(int32 index) const
                                                                        { return fParameters.ItemAt(index); }

                        DIESubroutineType*      Entry() const
                                                                        { return fEntry; }

private:
                        typedef BObjectList<DwarfFunctionParameter> ParameterList;

private:
                        DIESubroutineType*      fEntry;
                        DwarfType*                      fReturnType;
                        ParameterList           fParameters;
                        bool                            fHasVariableArguments;
};


class DwarfPointerToMemberType : public PointerToMemberType, public DwarfType {
public:
                                                                DwarfPointerToMemberType(
                                                                        DwarfTypeContext* typeContext,
                                                                        const BString& name,
                                                                        DIEPointerToMemberType* entry,
                                                                        DwarfCompoundType* containingType,
                                                                        DwarfType* baseType);
                                                                ~DwarfPointerToMemberType();

        virtual CompoundType*           ContainingType() const;
        virtual Type*                           BaseType() const;

        virtual DIEType*                        GetDIEType() const;

                        DIEPointerToMemberType* Entry() const
                                                                        { return fEntry; }

private:
                        DIEPointerToMemberType* fEntry;
                        DwarfCompoundType*      fContainingType;
                        DwarfType*                      fBaseType;
};


#endif  // DWARF_TYPES_H