root/src/kits/debugger/dwarf/AttributeValue.h
/*
 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
 * Distributed under the terms of the MIT License.
 */
#ifndef ATTRIBUTE_VALUE_H
#define ATTRIBUTE_VALUE_H

#include "AttributeClasses.h"
#include "Types.h"


class DebugInfoEntry;


struct AttributeValue {
        union {
                target_addr_t           address;
                struct {
                        const void*             data;
                        off_t                   length;
                }                                       block;
                uint64                          constant;
                bool                            flag;
                off_t                           pointer;
                DebugInfoEntry*         reference;
                const char*                     string;
        };

        uint16                          attributeForm;
        uint8                           attributeClass;
        bool                            isSigned;

        AttributeValue()
                :
                attributeClass(ATTRIBUTE_CLASS_UNKNOWN)
        {
        }

        ~AttributeValue()
        {
                Unset();
        }

        void SetToAddress(target_addr_t address)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_ADDRESS;
                this->address = address;
        }

        void SetToAddrPtr(off_t value)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_ADDRPTR;
                this->pointer = value;
        }

        void SetToBlock(const void* data, off_t length)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_BLOCK;
                block.data = data;
                block.length = length;
        }

        void SetToConstant(uint64 value, bool isSigned)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_CONSTANT;
                this->constant = value;
                this->isSigned = isSigned;
        }

        void SetToFlag(bool value)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_FLAG;
                this->flag = value;
        }

        void SetToLinePointer(off_t value)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_LINEPTR;
                this->pointer = value;
        }

        void SetToLocationList(off_t value)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_LOCLIST;
                this->pointer = value;
        }

        void SetToLocationListPointer(off_t value)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_LOCLISTPTR;
                this->pointer = value;
        }

        void SetToMacroPointer(off_t value)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_MACPTR;
                this->pointer = value;
        }

        void SetToRangeList(off_t value)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_RANGELIST;
                this->pointer = value;
        }

        void SetToRangeListPointer(off_t value)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_RANGELISTPTR;
                this->pointer = value;
        }

        void SetToReference(DebugInfoEntry* entry)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_REFERENCE;
                this->reference = entry;
        }

        void SetToString(const char* string)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_STRING;
                this->string = string;
        }

        void SetToStrOffsetsPtr(off_t value)
        {
                Unset();
                attributeClass = ATTRIBUTE_CLASS_STROFFSETSPTR;
                this->pointer = value;
        }

        void Unset()
        {
                attributeClass = ATTRIBUTE_CLASS_UNKNOWN;
        }

        const char* ToString(char* buffer, size_t size);
};


struct DynamicAttributeValue {
        union {
                uint64                          constant;
                DebugInfoEntry*         reference;
                struct {
                        const void*             data;
                        off_t                   length;
                }                                       block;
        };
        uint8                           attributeClass;

        DynamicAttributeValue()
                :
                attributeClass(ATTRIBUTE_CLASS_UNKNOWN)
        {
                this->constant = 0;
        }

        bool IsValid() const
        {
                return attributeClass != ATTRIBUTE_CLASS_UNKNOWN;
        }

        void SetTo(uint64 constant)
        {
                this->constant = constant;
                attributeClass = ATTRIBUTE_CLASS_CONSTANT;
        }

        void SetTo(DebugInfoEntry* reference)
        {
                this->reference = reference;
                attributeClass = ATTRIBUTE_CLASS_REFERENCE;
        }

        void SetTo(const void* data, off_t length)
        {
                block.data = data;
                block.length = length;
                attributeClass = ATTRIBUTE_CLASS_BLOCK;
        }
};


struct ConstantAttributeValue {
        union {
                uint64                          constant;
                const char*                     string;
                struct {
                        const void*             data;
                        off_t                   length;
                }                                       block;
        };
        uint8                           attributeClass;

        ConstantAttributeValue()
                :
                attributeClass(ATTRIBUTE_CLASS_UNKNOWN)
        {
        }

        bool IsValid() const
        {
                return attributeClass != ATTRIBUTE_CLASS_UNKNOWN;
        }

        void SetTo(uint64 constant)
        {
                this->constant = constant;
                attributeClass = ATTRIBUTE_CLASS_CONSTANT;
        }

        void SetTo(const char* string)
        {
                this->string = string;
                attributeClass = ATTRIBUTE_CLASS_STRING;
        }

        void SetTo(const void* data, off_t length)
        {
                block.data = data;
                block.length = length;
                attributeClass = ATTRIBUTE_CLASS_BLOCK;
        }
};


struct MemberLocation {
        union {
                uint64                          constant;
                off_t                           listOffset;
                struct {
                        const void*             data;
                        off_t                   length;
                }                                       expression;
        };
        uint8                           attributeClass;

        MemberLocation()
                :
                attributeClass(ATTRIBUTE_CLASS_UNKNOWN)
        {
        }

        bool IsValid() const
        {
                return attributeClass != ATTRIBUTE_CLASS_UNKNOWN;
        }

        bool IsConstant() const
        {
                return attributeClass == ATTRIBUTE_CLASS_CONSTANT;
        }

        bool IsExpression() const
        {
                return attributeClass == ATTRIBUTE_CLASS_BLOCK
                        && expression.data != NULL;
        }

        bool IsLocationList() const
        {
                return attributeClass == ATTRIBUTE_CLASS_LOCLIST;
        }

        void SetToConstant(uint64 constant)
        {
                this->constant = constant;
                attributeClass = ATTRIBUTE_CLASS_CONSTANT;
        }

        void SetToExpression(const void* data, off_t length)
        {
                expression.data = data;
                expression.length = length;
                attributeClass = ATTRIBUTE_CLASS_BLOCK;
        }

        void SetToLocationList(off_t listOffset)
        {
                this->listOffset = listOffset;
                attributeClass = ATTRIBUTE_CLASS_LOCLIST;
        }
};


struct LocationDescription {
        union {
                off_t                   listOffset;     // location list
                struct {
                        const void*     data;
                        off_t           length;
                }                               expression;     // location expression
        };
        uint8                           attributeClass;

        LocationDescription()
                :
                attributeClass(ATTRIBUTE_CLASS_BLOCK)
        {
                expression.data = NULL;
                expression.length = 0;
        }

        bool IsExpression() const
        {
                return attributeClass == ATTRIBUTE_CLASS_BLOCK
                        && expression.data != NULL;
        }

        bool IsLocationList() const
        {
                return attributeClass == ATTRIBUTE_CLASS_LOCLIST;
        }

        bool IsValid() const
        {
                return IsExpression() || IsLocationList();
        }

        void SetToLocationList(off_t offset)
        {
                listOffset = offset;
                attributeClass = ATTRIBUTE_CLASS_LOCLIST;
        }

        void SetToExpression(const void* data, off_t length)
        {
                expression.data = data;
                expression.length = length;
                attributeClass = ATTRIBUTE_CLASS_BLOCK;
        }
};


struct DeclarationLocation {
        uint32  file;
        uint32  line;
        uint32  column;

        DeclarationLocation()
                :
                file(0xffffffff),
                line(0xffffffff),
                column(0xffffffff)
        {
        }

        void SetFile(uint32 file)
        {
                this->file = file;
        }

        void SetLine(uint32 line)
        {
                this->line = line;
        }

        void SetColumn(uint32 column)
        {
                this->column = column;
        }

        bool IsFileSet() const
        {
                return file != 0xffffffff;
        }

        bool IsLineSet() const
        {
                return line != 0xffffffff;
        }

        bool IsColumnSet() const
        {
                return column != 0xffffffff;
        }
};

#endif  // ATTRIBUTE_VALUE_H