using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace CppSharp.AST
{
///
/// Virtual table component kind.
///
public enum VTableComponentKind
{
VCallOffset,
VBaseOffset,
OffsetToTop,
RTTI,
FunctionPointer,
CompleteDtorPointer,
DeletingDtorPointer,
UnusedFunctionPointer,
}
///
/// Represents a C++ virtual table component.
///
[DebuggerDisplay("{Kind}, {Offset}, {Declaration}")]
public struct VTableComponent
{
public VTableComponentKind Kind;
public ulong Offset;
public Declaration Declaration;
/// Method declaration (if Kind == FunctionPointer).
public Method Method
{
get
{
Debug.Assert(Kind == VTableComponentKind.FunctionPointer);
return Declaration as Method;
}
}
}
///
/// Represents a C++ virtual table layout.
///
public class VTableLayout
{
public List Components { get; set; }
public VTableLayout()
{
Components = new List();
}
}
///
/// Contains information about virtual function pointers.
///
public struct VFTableInfo
{
/// If nonzero, holds the vbtable index of the virtual base with the vfptr.
public ulong VBTableIndex;
/// This is the offset of the vfptr from the start of the last vbase,
/// or the complete type if there are no virtual bases.
public long VFPtrOffset;
/// This is the full offset of the vfptr from the start of the complete type.
public long VFPtrFullOffset;
/// Layout of the table at this pointer.
public VTableLayout Layout;
}
public enum RecordArgABI
{
///
/// Pass it using the normal C aggregate rules for the ABI,
/// potentially introducing extra copies and passing some
/// or all of it in registers.
///
Default = 0,
///
/// Pass it on the stack using its defined layout.
/// The argument must be evaluated directly into the correct
/// stack position in the arguments area, and the call machinery
/// must not move it or introduce extra copies.
///
DirectInMemory = 1,
/// Pass it as a pointer to temporary memory.
Indirect = 2
};
// Represents ABI-specific layout details for a class.
public class ClassLayout
{
public CppAbi ABI { get; set; }
/// Provides native argument ABI information.
public RecordArgABI ArgABI { get; set; }
/// Virtual function tables in Microsoft mode.
public List VFTables { get; set; }
/// Virtual table layout in Itanium mode.
public VTableLayout Layout { get; set; }
public ClassLayout()
{
VFTables = new List();
Fields = new List();
Bases = new List();
}
public List Fields { get; private set; }
public List Bases { get; private set; }
public ClassLayout(ClassLayout classLayout)
: this()
{
ABI = classLayout.ABI;
HasOwnVFPtr = classLayout.HasOwnVFPtr;
VBPtrOffset = classLayout.VBPtrOffset;
PrimaryBase = classLayout.PrimaryBase;
HasVirtualBases = classLayout.HasVirtualBases;
Alignment = classLayout.Alignment;
Size = classLayout.Size;
DataSize = classLayout.DataSize;
VFTables.AddRange(classLayout.VFTables);
if (classLayout.Layout != null)
{
Layout = new VTableLayout();
Layout.Components.AddRange(classLayout.Layout.Components);
}
}
///
/// Does this class provide its own virtual-function table
/// pointer, rather than inheriting one from a primary base
/// class? If so, it is at offset zero.
///
public bool HasOwnVFPtr;
///
/// Get the offset for virtual base table pointer.
/// This is only meaningful with the Microsoft ABI.
///
public long VBPtrOffset;
///
/// Primary base for this record.
///
public Class PrimaryBase;
public bool HasVirtualBases;
public int Alignment;
public int Size;
public int DataSize;
public IList VTablePointers
{
get
{
if (vTablePointers == null)
{
vTablePointers = ABI == CppAbi.Microsoft ?
new List(Fields.Where(f => f.IsVTablePtr)) :
new List { Fields.First(f => f.IsVTablePtr) };
}
return vTablePointers;
}
}
///
/// Indicates whether this class layout has a subclass at a non-zero offset.
///
public bool HasSubclassAtNonZeroOffset { get; set; }
private List vTablePointers;
}
}