⛏️ index : haiku.git

/*
 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
 * Copyright 2013-2018, Rene Gollent, rene@gollent.com.
 * Distributed under the terms of the MIT License.
 */
#ifndef DEBUG_INFO_ENTRIES_H
#define DEBUG_INFO_ENTRIES_H


#include "DebugInfoEntry.h"

#include "AttributeValue.h"


// common:
// DW_AT_name
// // not supported by all types:
// DW_AT_allocated
// DW_AT_associated
// DW_AT_data_location
// DW_AT_start_scope

// modified:
// DW_AT_type

// declared:
// DECL
// DW_AT_accessibility		// !file, !pointer to member
// DW_AT_declaration		// !file
// DW_AT_abstract_origin	// !interface
// DW_AT_description		// !interface
// DW_AT_visibility			// !interface

// derived: declared
// DW_AT_type

// addressing: modified
// DW_AT_address_class

// compound: declared
// DW_AT_byte_size			// !interface
// DW_AT_specification		// !interface

// class base: compound

// array index: derived
// DW_AT_bit_stride
// DW_AT_byte_stride
// DW_AT_byte_size


// unspecified: common
// DECL
// DW_AT_description



// class/structure: class base

// interface: class base

// union: compound

// string: declared
// DW_AT_byte_size
// DW_AT_string_length

// subroutine: declared
// DW_AT_address_class
// DW_AT_prototyped
// DW_AT_type


// enumeration: array index
// DW_AT_specification

// pointer to member: derived
// DW_AT_address_class
// DW_AT_containing_type
// DW_AT_use_location

// set: derived
// DW_AT_byte_size

// subrange: array index
// DW_AT_count
// DW_AT_lower_bound
// DW_AT_threads_scaled
// DW_AT_upper_bound

// array: derived
// DW_AT_bit_stride
// DW_AT_byte_size
// DW_AT_ordering
// DW_AT_specification

// typedef: derived

// file: derived
// DW_AT_byte_size


// shared: modified
// DECL
// DW_AT_count

// const: modified

// packed: modified

// volatile: modified
// DECL

// restrict: modified

// pointer: addressing
// DW_AT_specification

// reference: addressing


// basetype:
// DW_AT_binary_scale
// DW_AT_bit_offset
// DW_AT_bit_size
// DW_AT_byte_size
// DW_AT_decimal_scale
// DW_AT_decimal_sign
// DW_AT_description
// DW_AT_digit_count
// DW_AT_encoding
// DW_AT_endianity
// DW_AT_picture_string
// DW_AT_small


class DIECompileUnitBase : public DebugInfoEntry {
public:
								DIECompileUnitBase();
								~DIECompileUnitBase();

	virtual	status_t			InitAfterAttributes(
									DebugInfoEntryInitInfo& info);

	virtual	const char*			Name() const;

			const char*			CompilationDir() const
									{ return fCompilationDir; }

			uint16				Language() const	{ return fLanguage; }

			const DebugInfoEntryList& Types() const	{ return fTypes; }
			const DebugInfoEntryList& OtherChildren() const
										{ return fOtherChildren; }
			off_t				AddressRangesOffset() const
										{ return fAddressRangesOffset; }

			target_addr_t		LowPC() const	{ return fLowPC; }
			target_addr_t		HighPC() const	{ return fHighPC; }

			off_t				StatementListOffset() const
									{ return fStatementListOffset; }

			bool				ContainsMainSubprogram() const
									{ return fContainsMainSubprogram; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

	virtual	status_t			AddAttribute_name(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_comp_dir(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_low_pc(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_high_pc(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_producer(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_stmt_list(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_macro_info(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_base_types(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_language(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_identifier_case(
									uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_use_UTF8(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_ranges(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_main_subprogram(
									uint16 attributeName,
									const AttributeValue& value);

//TODO:
//	virtual	status_t			AddAttribute_segment(uint16 attributeName,
//									const AttributeValue& value);

// TODO: DW_AT_import

protected:
			const char*			fName;
			const char*			fCompilationDir;
			target_addr_t		fLowPC;
			target_addr_t		fHighPC;
			off_t				fStatementListOffset;
			off_t				fMacroInfoOffset;
			off_t				fAddressRangesOffset;
			DIECompileUnitBase*	fBaseTypesUnit;
			DebugInfoEntryList	fTypes;
			DebugInfoEntryList	fOtherChildren;
			uint16				fLanguage;
			uint8				fIdentifierCase;
			bool				fUseUTF8;
			bool				fContainsMainSubprogram;
};


class DIEType : public DebugInfoEntry {
public:
								DIEType();

	virtual	bool				IsType() const;

	virtual	const char*			Name() const;

	virtual	bool				IsDeclaration() const;
	virtual	const DynamicAttributeValue* ByteSize() const;

	virtual	status_t			AddAttribute_name(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_allocated(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_associated(uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_data_location
// DW_AT_start_scope

protected:
			const char*			fName;
			DynamicAttributeValue fAllocated;
			DynamicAttributeValue fAssociated;
};


class DIEModifiedType : public DIEType {
public:
								DIEModifiedType();

			DIEType*			GetType() const	{ return fType; }

	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

protected:
			DIEType*			fType;
};


class DIEAddressingType : public DIEModifiedType {
public:
								DIEAddressingType();

	virtual	status_t			AddAttribute_address_class(uint16 attributeName,
									const AttributeValue& value);

protected:
			uint8				fAddressClass;
};


class DIEDeclaredType : public DIEType {
public:
								DIEDeclaredType();

	virtual	const char*			Description() const;
	virtual	DebugInfoEntry*		AbstractOrigin() const;

	virtual DebugInfoEntry*		SignatureType() const;

	virtual	bool				IsDeclaration() const;

	virtual	status_t			AddAttribute_accessibility(uint16 attributeName,
									const AttributeValue& value);
										// TODO: !file, !pointer to member
	virtual	status_t			AddAttribute_declaration(uint16 attributeName,
									const AttributeValue& value);
										// TODO: !file
	virtual	status_t			AddAttribute_description(uint16 attributeName,
									const AttributeValue& value);
										// TODO: !interface
	virtual	status_t			AddAttribute_abstract_origin(
									uint16 attributeName,
									const AttributeValue& value);
										// TODO: !interface
	virtual	status_t			AddAttribute_signature(uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_visibility			// !interface

protected:
	virtual	DeclarationLocation* GetDeclarationLocation();

protected:
			const char*			fDescription;
			DeclarationLocation	fDeclarationLocation;
			DebugInfoEntry*		fAbstractOrigin;
			DebugInfoEntry*		fSignatureType;
			uint8				fAccessibility;
			bool				fDeclaration;
};


class DIEDerivedType : public DIEDeclaredType {
public:
								DIEDerivedType();

			DIEType*			GetType() const	{ return fType; }

	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

protected:
			DIEType*			fType;
};


class DIECompoundType : public DIEDeclaredType {
public:
								DIECompoundType();

	virtual	bool				IsNamespace() const;

	virtual	DebugInfoEntry*		Specification() const;

	virtual	const DynamicAttributeValue* ByteSize() const;

			const DebugInfoEntryList& DataMembers() const
									{ return fDataMembers; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

	virtual	status_t			AddAttribute_byte_size(uint16 attributeName,
									const AttributeValue& value);
										// TODO: !interface
	virtual	status_t			AddAttribute_specification(uint16 attributeName,
									const AttributeValue& value);
										// TODO: !interface

protected:
			DynamicAttributeValue fByteSize;
			DIECompoundType*	fSpecification;
			DebugInfoEntryList	fDataMembers;
};


class DIEClassBaseType : public DIECompoundType {
public:
								DIEClassBaseType();

			const DebugInfoEntryList& BaseTypes() const
									{ return fBaseTypes; }
			const DebugInfoEntryList& MemberFunctions() const
									{ return fMemberFunctions; }
			const DebugInfoEntryList& InnerTypes() const
									{ return fInnerTypes; }
			const DebugInfoEntryList& TemplateParameters() const
									{ return fTemplateParameters; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

protected:
			DebugInfoEntryList	fBaseTypes;
			DebugInfoEntryList	fFriends;
			DebugInfoEntryList	fAccessDeclarations;
			DebugInfoEntryList	fMemberFunctions;
			DebugInfoEntryList	fInnerTypes;
			DebugInfoEntryList	fTemplateParameters;
};


class DIENamedBase : public DebugInfoEntry {
public:
								DIENamedBase();

	virtual	const char*			Name() const;
	virtual	const char*			Description() const;

	virtual	status_t			AddAttribute_name(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_description(uint16 attributeName,
									const AttributeValue& value);

protected:
			const char*			fName;
			const char*			fDescription;
};


class DIEDeclaredBase : public DebugInfoEntry {
public:
								DIEDeclaredBase();

protected:
	virtual	DeclarationLocation* GetDeclarationLocation();

protected:
			DeclarationLocation	fDeclarationLocation;
};


class DIEDeclaredNamedBase : public DIEDeclaredBase {
public:
								DIEDeclaredNamedBase();

	virtual	const char*			Name() const;
	virtual	const char*			Description() const;

			uint8				Accessibility() const { return fAccessibility; }
			uint8				Visibility() const	{ return fVisibility; }
	virtual	bool				IsDeclaration() const;

	virtual	status_t			AddAttribute_name(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_description(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_accessibility(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_declaration(uint16 attributeName,
									const AttributeValue& value);

protected:
			const char*			fName;
			const char*			fDescription;
			uint8				fAccessibility;
			uint8				fVisibility;
			bool				fDeclaration;
};


class DIEArrayIndexType : public DIEDerivedType {
public:
								DIEArrayIndexType();

	virtual	const DynamicAttributeValue* ByteSize() const;

			const DynamicAttributeValue* BitStride() const
									{ return &fBitStride; }
			const DynamicAttributeValue* ByteStride() const
									{ return &fByteStride; }

	virtual	status_t			AddAttribute_bit_stride(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_byte_size(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_byte_stride(uint16 attributeName,
									const AttributeValue& value);

private:
			DynamicAttributeValue fBitStride;
			DynamicAttributeValue fByteSize;
			DynamicAttributeValue fByteStride;
};


// #pragma mark -


class DIEArrayType : public DIEDerivedType {
public:
								DIEArrayType();

	virtual	uint16				Tag() const;

	virtual	status_t			InitAfterHierarchy(
									DebugInfoEntryInitInfo& info);

	virtual	DebugInfoEntry*		Specification() const;

	virtual	const DynamicAttributeValue* ByteSize() const;

			const DynamicAttributeValue* BitStride() const
									{ return &fBitStride; }

			const DebugInfoEntryList& Dimensions() const
									{ return fDimensions; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

	virtual	status_t			AddAttribute_ordering(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_bit_stride(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_stride_size(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_byte_size(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_specification(uint16 attributeName,
									const AttributeValue& value);

private:
			DynamicAttributeValue fBitStride;
			DynamicAttributeValue fByteSize;
			DebugInfoEntryList	fDimensions;
			DIEArrayType*		fSpecification;
			uint8				fOrdering;
};


class DIEClassType : public DIEClassBaseType {
public:
								DIEClassType();

	virtual	uint16				Tag() const;
};


class DIEEntryPoint : public DebugInfoEntry {
public:
// TODO: Maybe introduce a common base class for DIEEntryPoint and
// DIESubprogram.
								DIEEntryPoint();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_address_class
// DW_AT_description
// DW_AT_frame_base
// DW_AT_low_pc
// DW_AT_name
// DW_AT_return_addr
// DW_AT_segment
// DW_AT_static_link
// DW_AT_type
};


class DIEEnumerationType : public DIEArrayIndexType {
public:
								DIEEnumerationType();

	virtual	uint16				Tag() const;

	virtual	DebugInfoEntry*		Specification() const;

			const DebugInfoEntryList& Enumerators() const
									{ return fEnumerators; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

	virtual	status_t			AddAttribute_specification(uint16 attributeName,
									const AttributeValue& value);

private:
			DIEEnumerationType*	fSpecification;
			DebugInfoEntryList	fEnumerators;
};


class DIEFormalParameter : public DIEDeclaredNamedBase {
public:
								DIEFormalParameter();

	virtual	uint16				Tag() const;

	virtual	DebugInfoEntry*		AbstractOrigin() const;
	virtual	LocationDescription* GetLocationDescription();

			DIEType*			GetType() const	{ return fType; }

			const ConstantAttributeValue* ConstValue() const
									{ return &fValue; }

			bool				IsArtificial() const { return fArtificial; }

	virtual	status_t			AddAttribute_abstract_origin(
									uint16 attributeName,
									const AttributeValue& value);
	virtual status_t			AddAttribute_artificial(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_const_value(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_default_value
// DW_AT_endianity
// DW_AT_is_optional
// DW_AT_segment
// DW_AT_variable_parameter

private:
			LocationDescription	fLocationDescription;
			DebugInfoEntry*		fAbstractOrigin;
			DIEType*			fType;
			ConstantAttributeValue fValue;
			bool				fArtificial;
};


class DIEImportedDeclaration : public DIEDeclaredNamedBase {
public:
								DIEImportedDeclaration();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_import
// DW_AT_start_scope
};


class DIELabel : public DIEDeclaredNamedBase {
public:
								DIELabel();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_abstract_origin
// DW_AT_low_pc
// DW_AT_segment
// DW_AT_start_scope
};


class DIELexicalBlock : public DIENamedBase {
public:
								DIELexicalBlock();

	virtual	uint16				Tag() const;

	virtual	DebugInfoEntry*		AbstractOrigin() const;

			off_t				AddressRangesOffset() const
										{ return fAddressRangesOffset; }

			target_addr_t		LowPC() const	{ return fLowPC; }
			target_addr_t		HighPC() const	{ return fHighPC; }

			const DebugInfoEntryList& Variables() const	{ return fVariables; }
			const DebugInfoEntryList& Blocks() const	{ return fBlocks; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

	virtual	status_t			AddAttribute_low_pc(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_high_pc(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_ranges(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_abstract_origin(
									uint16 attributeName,
									const AttributeValue& value);

protected:
			DebugInfoEntryList	fVariables;
			DebugInfoEntryList	fBlocks;
			target_addr_t		fLowPC;
			target_addr_t		fHighPC;
			off_t				fAddressRangesOffset;
			DIELexicalBlock*	fAbstractOrigin;

// TODO:
// DW_AT_segment
};


class DIEMember : public DIEDeclaredNamedBase {
public:
								DIEMember();

	virtual	uint16				Tag() const;

			DIEType*			GetType() const	{ return fType; }
			const DynamicAttributeValue* ByteSize() const
									{ return &fByteSize; }
			const DynamicAttributeValue* BitOffset() const
									{ return &fBitOffset; }
			const DynamicAttributeValue* DataBitOffset() const
									{ return &fDataBitOffset; }
			const DynamicAttributeValue* BitSize() const
									{ return &fBitSize; }
			const MemberLocation* Location() const
									{ return &fLocation; }

	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_byte_size(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_bit_size(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_bit_offset(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_data_bit_offset(
									uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_data_member_location(
									uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_mutable

private:
			DIEType*			fType;
			DynamicAttributeValue fByteSize;
			DynamicAttributeValue fBitOffset;
			DynamicAttributeValue fDataBitOffset;
			DynamicAttributeValue fBitSize;
			MemberLocation		fLocation;
};


class DIEPointerType : public DIEAddressingType {
public:
								DIEPointerType();

	virtual	uint16				Tag() const;

	virtual	DebugInfoEntry*		Specification() const;

	virtual	status_t			AddAttribute_specification(uint16 attributeName,
									const AttributeValue& value);

private:
			DIEPointerType*		fSpecification;
};


class DIEReferenceType : public DIEAddressingType {
public:
								DIEReferenceType();

	virtual	uint16				Tag() const;
};


class DIECompileUnit : public DIECompileUnitBase {
public:
								DIECompileUnit();

	virtual	uint16				Tag() const;
};


class DIEStringType : public DIEDeclaredType {
public:
								DIEStringType();

	virtual	uint16				Tag() const;

	virtual	const DynamicAttributeValue* ByteSize() const;

	virtual	status_t			AddAttribute_byte_size(uint16 attributeName,
									const AttributeValue& value);

private:
			DynamicAttributeValue fByteSize;
// TODO:
// DW_AT_string_length
};


class DIEStructureType : public DIEClassBaseType {
public:
								DIEStructureType();

	virtual	uint16				Tag() const;
};


class DIESubroutineType : public DIEDeclaredType {
public:
								DIESubroutineType();

	virtual	uint16				Tag() const;

			DIEType*			ReturnType() const	{ return fReturnType; }

			const DebugInfoEntryList& Parameters() const { return fParameters; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

	virtual	status_t			AddAttribute_address_class(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_prototyped(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

protected:
			DebugInfoEntryList	fParameters;
			DIEType*			fReturnType;
			uint8				fAddressClass;
			bool				fPrototyped;
};


class DIETypedef : public DIEDerivedType {
public:
								DIETypedef();

	virtual	uint16				Tag() const;
};


class DIEUnionType : public DIECompoundType {
public:
								DIEUnionType();

	virtual	uint16				Tag() const;
};


class DIEUnspecifiedParameters : public DIEDeclaredBase {
public:
								DIEUnspecifiedParameters();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_abstract_origin
// DW_AT_artificial
};


class DIEVariant : public DIEDeclaredBase {
public:
								DIEVariant();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_accessibility
// DW_AT_abstract_origin
// DW_AT_declaration
// DW_AT_discr_list
// DW_AT_discr_value
};


class DIECommonBlock : public DIEDeclaredNamedBase {
public:
								DIECommonBlock();

	virtual	uint16				Tag() const;

	virtual	LocationDescription* GetLocationDescription();

// TODO:
// DW_AT_segment

private:
			LocationDescription	fLocationDescription;
};


class DIECommonInclusion : public DIEDeclaredBase {
public:
								DIECommonInclusion();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_common_reference
// DW_AT_declaration
// DW_AT_visibility

};


class DIEInheritance : public DIEDeclaredBase {
public:
								DIEInheritance();

	virtual	uint16				Tag() const;

			DIEType*			GetType() const	{ return fType; }
			const MemberLocation* Location() const
									{ return &fLocation; }

	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_data_member_location(
									uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_accessibility
// DW_AT_virtuality

private:
			DIEType*			fType;
			MemberLocation		fLocation;
};


class DIEInlinedSubroutine : public DebugInfoEntry {
public:
								DIEInlinedSubroutine();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_abstract_origin
// DW_AT_call_column
// DW_AT_call_file
// DW_AT_call_line
// DW_AT_entry_pc
// DW_AT_high_pc
// DW_AT_low_pc
// DW_AT_ranges
// DW_AT_return_addr
// DW_AT_segment
// DW_AT_start_scope
// DW_AT_trampoline
};


class DIEModule : public DIEDeclaredNamedBase {
public:
								DIEModule();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_entry_pc
// DW_AT_high_pc
// DW_AT_low_pc
// DW_AT_priority
// DW_AT_ranges
// DW_AT_segment
// DW_AT_specification
};


class DIEPointerToMemberType : public DIEDerivedType {
public:
								DIEPointerToMemberType();

	virtual	uint16				Tag() const;

			DIECompoundType*	ContainingType() const
									{ return fContainingType; }

			const LocationDescription& UseLocation() const
									{ return fUseLocation; }

	virtual	status_t			AddAttribute_address_class(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_containing_type(
									uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_use_location(uint16 attributeName,
									const AttributeValue& value);

protected:
			DIECompoundType*	fContainingType;
			LocationDescription	fUseLocation;
			uint8				fAddressClass;
};


class DIESetType : public DIEDerivedType {
public:
								DIESetType();

	virtual	uint16				Tag() const;

	virtual	const DynamicAttributeValue* ByteSize() const;

	virtual	status_t			AddAttribute_byte_size(uint16 attributeName,
									const AttributeValue& value);

private:
			DynamicAttributeValue fByteSize;
};


class DIESubrangeType : public DIEArrayIndexType {
public:
								DIESubrangeType();

	virtual	uint16				Tag() const;

			const DynamicAttributeValue* LowerBound() const
									{ return &fLowerBound; }
			const DynamicAttributeValue* UpperBound() const
									{ return &fUpperBound; }
			const DynamicAttributeValue* Count() const
									{ return &fCount; }

	virtual	status_t			AddAttribute_count(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_lower_bound(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_upper_bound(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_threads_scaled(
									uint16 attributeName,
									const AttributeValue& value);

private:
			DynamicAttributeValue fCount;
			DynamicAttributeValue fLowerBound;
			DynamicAttributeValue fUpperBound;
			bool				fThreadsScaled;
};


class DIEWithStatement : public DebugInfoEntry {
public:
								DIEWithStatement();

	virtual	uint16				Tag() const;

			DIEType*			GetType() const	{ return fType; }

	virtual	LocationDescription* GetLocationDescription();

	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_accessibility
// DW_AT_address_class
// DW_AT_declaration
// DW_AT_high_pc
// DW_AT_low_pc
// DW_AT_ranges
// DW_AT_segment
// DW_AT_visibility

private:
			DIEType*			fType;
			LocationDescription	fLocationDescription;
};


class DIEAccessDeclaration : public DIEDeclaredNamedBase {
public:
								DIEAccessDeclaration();

	virtual	uint16				Tag() const;
};


class DIEBaseType : public DIEType {
public:
								DIEBaseType();

	virtual	uint16				Tag() const;

	virtual	const DynamicAttributeValue* ByteSize() const;
			const DynamicAttributeValue* BitOffset() const
									{ return &fBitOffset; }
			const DynamicAttributeValue* DataBitOffset() const
									{ return &fDataBitOffset; }
			const DynamicAttributeValue* BitSize() const
									{ return &fBitSize; }
			uint8				Encoding() const	{ return fEncoding; }
			uint8				Endianity() const	{ return fEndianity; }

	virtual	status_t			AddAttribute_encoding(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_byte_size(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_bit_size(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_bit_offset(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_data_bit_offset(
									uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_endianity(uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_binary_scale
// DW_AT_decimal_scale
// DW_AT_decimal_sign
// DW_AT_description
// DW_AT_digit_count
// DW_AT_picture_string
// DW_AT_small

private:
			DynamicAttributeValue fByteSize;
			DynamicAttributeValue fBitOffset;
			DynamicAttributeValue fDataBitOffset;
			DynamicAttributeValue fBitSize;
			uint8				fEncoding;
			uint8				fEndianity;
};


class DIECatchBlock : public DebugInfoEntry {
public:
								DIECatchBlock();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_abstract_origin
// DW_AT_high_pc
// DW_AT_low_pc
// DW_AT_ranges
// DW_AT_segment
};


class DIEConstType : public DIEModifiedType {
public:
								DIEConstType();

	virtual	uint16				Tag() const;
};


class DIEConstant : public DIEDeclaredNamedBase {
public:
								DIEConstant();

	virtual	uint16				Tag() const;

			DIEType*			GetType() const	{ return fType; }

			const ConstantAttributeValue* ConstValue() const
									{ return &fValue; }

	virtual	status_t			AddAttribute_const_value(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_endianity
// DW_AT_external
// DW_AT_start_scope

private:
			DIEType*			fType;
			ConstantAttributeValue fValue;
};


class DIEEnumerator : public DIEDeclaredNamedBase {
public:
								DIEEnumerator();

	virtual	uint16				Tag() const;

			const ConstantAttributeValue* ConstValue() const
									{ return &fValue; }

	virtual	status_t			AddAttribute_const_value(uint16 attributeName,
									const AttributeValue& value);

private:
			ConstantAttributeValue fValue;
};


class DIEFileType : public DIEDerivedType {
public:
								DIEFileType();

	virtual	uint16				Tag() const;

	virtual	const DynamicAttributeValue* ByteSize() const;

	virtual	status_t			AddAttribute_byte_size(uint16 attributeName,
									const AttributeValue& value);

private:
			DynamicAttributeValue fByteSize;
};


class DIEFriend : public DIEDeclaredBase {
public:
								DIEFriend();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_abstract_origin
// DW_AT_friend
};


class DIENameList : public DIEDeclaredNamedBase {
public:
								DIENameList();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_abstract_origin
};


class DIENameListItem : public DIEDeclaredBase {
public:
								DIENameListItem();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_namelist_item
};


class DIENamespace : public DIEDeclaredNamedBase {
public:
								DIENamespace();

	virtual	uint16				Tag() const;

	virtual	bool				IsNamespace() const;

			const DebugInfoEntryList& Children() const
										{ return fChildren; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

private:
			DebugInfoEntryList	fChildren;

// TODO:
// DW_AT_extension
// DW_AT_start_scope
};


class DIEPackedType : public DIEModifiedType {
public:
								DIEPackedType();

	virtual	uint16				Tag() const;
};


class DIESubprogram : public DIENamespace {
public:
								DIESubprogram();
								~DIESubprogram();

	virtual	uint16				Tag() const;

	virtual	DebugInfoEntry*		Specification() const;
	virtual	DebugInfoEntry*		AbstractOrigin() const;

			off_t				AddressRangesOffset() const
										{ return fAddressRangesOffset; }

			target_addr_t		LowPC() const	{ return fLowPC; }
			target_addr_t		HighPC() const	{ return fHighPC; }

			const LocationDescription* FrameBase() const { return &fFrameBase; }

			const DebugInfoEntryList Parameters() const	{ return fParameters; }
			const DebugInfoEntryList Variables() const	{ return fVariables; }
			const DebugInfoEntryList Blocks() const		{ return fBlocks; }
			const DebugInfoEntryList TemplateTypeParameters() const
										{ return fTemplateTypeParameters; }
			const DebugInfoEntryList TemplateValueParameters() const
										{ return fTemplateValueParameters; }
			const DebugInfoEntryList CallSites() const
										{ return fCallSites; }

			bool				IsPrototyped() const	{ return fPrototyped; }
			uint8				Inline() const			{ return fInline; }
			bool				IsArtificial() const	{ return fArtificial; }
			uint8				CallingConvention() const
										{ return fCallingConvention; }
			bool				IsMain() const			{ return fMain; }

			DIEType*			ReturnType() const		{ return fReturnType; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

	virtual	status_t			AddAttribute_low_pc(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_high_pc(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_ranges(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_specification(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_address_class(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_prototyped(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_inline(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_abstract_origin(
									uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_frame_base(
									uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_artificial(
									uint16 attributeName,
									const AttributeValue& value);
	virtual status_t			AddAttribute_calling_convention(
									uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_main_subprogram(
									uint16 attributeName,
									const AttributeValue& value);


protected:
			DebugInfoEntryList	fParameters;
			DebugInfoEntryList	fVariables;
			DebugInfoEntryList	fBlocks;
			DebugInfoEntryList	fTemplateTypeParameters;
			DebugInfoEntryList	fTemplateValueParameters;
			DebugInfoEntryList	fCallSites;
			target_addr_t		fLowPC;
			target_addr_t		fHighPC;
			off_t				fAddressRangesOffset;
			DIESubprogram*		fSpecification;
			DIESubprogram*		fAbstractOrigin;
			DIEType*			fReturnType;
			LocationDescription	fFrameBase;
			uint8				fAddressClass;
			bool				fPrototyped;
			uint8				fInline;
			bool				fMain;
			bool				fArtificial;
			uint8				fCallingConvention;

// TODO:
// DW_AT_elemental
// DW_AT_entry_pc
// DW_AT_explicit
// DW_AT_external
// DW_AT_object_pointer
// DW_AT_pure
// DW_AT_recursive
// DW_AT_return_addr
// DW_AT_segment
// DW_AT_start_scope
// DW_AT_static_link
// DW_AT_trampoline
// DW_AT_virtuality
// DW_AT_vtable_elem_location
};


class DIETemplateTypeParameter : public DIEDeclaredNamedBase {
public:
								DIETemplateTypeParameter();

	virtual	uint16				Tag() const;

			DIEType*			GetType() const	{ return fType; }

	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

private:
			DIEType*			fType;
};


class DIETemplateValueParameter : public DIEDeclaredNamedBase {
public:
								DIETemplateValueParameter();

	virtual	uint16				Tag() const;

			DIEType*			GetType() const	{ return fType; }

			const ConstantAttributeValue* ConstValue() const
									{ return &fValue; }

	virtual	status_t			AddAttribute_const_value(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

private:
			DIEType*			fType;
			ConstantAttributeValue fValue;
};


class DIEThrownType : public DIEDeclaredBase {
public:
								DIEThrownType();

	virtual	uint16				Tag() const;

			DIEType*			GetType() const	{ return fType; }

	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_allocated
// DW_AT_associated
// DW_AT_data_location

private:
			DIEType*			fType;
};


class DIETryBlock : public DebugInfoEntry {
public:
								DIETryBlock();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_abstract_origin
// DW_AT_high_pc
// DW_AT_low_pc
// DW_AT_ranges
// DW_AT_segment
};


class DIEVariantPart : public DIEDeclaredBase {
public:
								DIEVariantPart();

	virtual	uint16				Tag() const;

			DIEType*			GetType() const	{ return fType; }

	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_abstract_origin
// DW_AT_accessibility
// DW_AT_declaration
// DW_AT_discr

private:
			DIEType*			fType;
};


class DIEVariable : public DIEDeclaredNamedBase {
public:
								DIEVariable();

	virtual	uint16				Tag() const;

	virtual	DebugInfoEntry*		Specification() const;
	virtual	DebugInfoEntry*		AbstractOrigin() const;

	virtual	LocationDescription* GetLocationDescription();

			DIEType*			GetType() const	{ return fType; }

			const ConstantAttributeValue* ConstValue() const
									{ return &fValue; }

			uint64				StartScope() const	{ return fStartScope; }

			bool				IsExternal() const	{ return fIsExternal; }

	virtual	status_t			AddAttribute_const_value(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_type(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_specification(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_abstract_origin(
									uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_start_scope(
									uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_external(
									uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_endianity
// DW_AT_segment

private:
			LocationDescription	fLocationDescription;
			ConstantAttributeValue fValue;
			DIEType*			fType;
			DebugInfoEntry*		fSpecification;
			DIEVariable*		fAbstractOrigin;
			uint64				fStartScope;
			bool				fIsExternal;
};


class DIEVolatileType : public DIEModifiedType {
public:
								DIEVolatileType();

	virtual	uint16				Tag() const;

	virtual	status_t			AddAttribute_decl_file(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_decl_line(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_decl_column(uint16 attributeName,
									const AttributeValue& value);

private:
			DeclarationLocation	fDeclarationLocation;
};


class DIEDwarfProcedure : public DebugInfoEntry {
public:
								DIEDwarfProcedure();

	virtual	uint16				Tag() const;

	virtual	LocationDescription* GetLocationDescription();

private:
			LocationDescription	fLocationDescription;
};


class DIERestrictType : public DIEModifiedType {
public:
								DIERestrictType();

	virtual	uint16				Tag() const;
};


class DIEInterfaceType : public DIEClassBaseType {
public:
								DIEInterfaceType();

	virtual	uint16				Tag() const;
};


class DIEImportedModule : public DIEDeclaredBase {
public:
								DIEImportedModule();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_import
// DW_AT_start_scope
};


class DIEUnspecifiedType : public DIEType {
public:
								DIEUnspecifiedType();

	virtual	uint16				Tag() const;

	virtual	status_t			AddAttribute_decl_file(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_decl_line(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_decl_column(uint16 attributeName,
									const AttributeValue& value);

// TODO:
// DW_AT_description

private:
			DeclarationLocation	fDeclarationLocation;
};


class DIEPartialUnit : public DIECompileUnitBase {
public:
								DIEPartialUnit();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_description
};


class DIEImportedUnit : public DebugInfoEntry {
public:
								DIEImportedUnit();

	virtual	uint16				Tag() const;

// TODO:
// DW_AT_import
};


class DIECondition : public DIEDeclaredNamedBase {
public:
								DIECondition();

	virtual	uint16				Tag() const;
};


class DIESharedType : public DIEModifiedType {
public:
								DIESharedType();

	virtual	uint16				Tag() const;

	virtual	status_t			AddAttribute_count(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_decl_file(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_decl_line(uint16 attributeName,
									const AttributeValue& value);
	virtual	status_t			AddAttribute_decl_column(uint16 attributeName,
									const AttributeValue& value);

private:
			DynamicAttributeValue fBlockSize;
			DeclarationLocation	fDeclarationLocation;
};


class DIETypeUnit : public DIECompileUnitBase {
public:
								DIETypeUnit();

	virtual	uint16				Tag() const;
};


class DIERValueReferenceType : public DIEReferenceType {
public:
								DIERValueReferenceType();

	virtual	uint16				Tag() const;
};


class DIETemplateTemplateParameter : public DIEDeclaredBase {
public:
								DIETemplateTemplateParameter();

	virtual	uint16				Tag() const;

	virtual	const char*			Name() const;

	virtual	status_t			AddAttribute_name(uint16 attributeName,
									const AttributeValue& value);

private:
			const char*			fName;
};


class DIETemplateTypeParameterPack : public DIEDeclaredBase {
public:
								DIETemplateTypeParameterPack();

	virtual	uint16				Tag() const;

	virtual	const char*			Name() const;

	virtual	status_t			AddAttribute_name(uint16 attributeName,
									const AttributeValue& value);

			const DebugInfoEntryList& Children() const
										{ return fChildren; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

private:
			const char*			fName;
			DebugInfoEntryList	fChildren;
};


class DIETemplateValueParameterPack : public DIEDeclaredBase {
public:
								DIETemplateValueParameterPack();

	virtual	uint16				Tag() const;

	virtual	const char*			Name() const;

	virtual	status_t			AddAttribute_name(uint16 attributeName,
									const AttributeValue& value);

			const DebugInfoEntryList& Children() const
										{ return fChildren; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

private:
			const char*			fName;
			DebugInfoEntryList	fChildren;
};


class DIECallSite : public DIEDeclaredBase {
public:
								DIECallSite();

	virtual	uint16				Tag() const;

	virtual	const char*			Name() const;

	virtual	status_t			AddAttribute_name(uint16 attributeName,
									const AttributeValue& value);

			const DebugInfoEntryList& Children() const
										{ return fChildren; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

private:
			const char*			fName;
			DebugInfoEntryList	fChildren;
};


class DIECallSiteParameter : public DIEDeclaredBase {
public:
								DIECallSiteParameter();

	virtual	uint16				Tag() const;

	virtual	const char*			Name() const;

	virtual	status_t			AddAttribute_name(uint16 attributeName,
									const AttributeValue& value);

			const DebugInfoEntryList& Children() const
										{ return fChildren; }

	virtual	status_t			AddChild(DebugInfoEntry* child);

private:
			const char*			fName;
			DebugInfoEntryList	fChildren;
};


// #pragma mark - DebugInfoEntryFactory


class DebugInfoEntryFactory {
public:
								DebugInfoEntryFactory();

			status_t			CreateDebugInfoEntry(uint16 tag,
									DebugInfoEntry*& entry);
};


#endif	// DEBUG_INFO_ENTRIES_H