use num_enum::TryFromPrimitive;

/// DWARF language identifiers
///
/// `dwarf::SourceLanguage` in LLVM's `Dwarf.h`
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u32)]
#[non_exhaustive]
pub enum SourceLanguage {
    C89 = 0x0001,
    C = 0x0002,
    Ada83 = 0x0003,
    Cpp = 0x0004,
    Cobol74 = 0x0005,
    Cobol85 = 0x0006,
    Fortran77 = 0x0007,
    Fortran90 = 0x0008,
    Pascal83 = 0x0009,
    Modula2 = 0x000a,
    Java = 0x000b,
    C99 = 0x000c,
    Ada95 = 0x000d,
    Fortran95 = 0x000e,
    PLI = 0x000f,
    ObjC = 0x0010,
    ObjCpp = 0x0011,
    UPC = 0x0012,
    D = 0x0013,
    Python = 0x0014,
    OpenCL = 0x0015,
    Go = 0x0016,
    Modula3 = 0x0017,
    Haskell = 0x0018,
    Cpp03 = 0x0019,
    Cpp11 = 0x001a,
    OCaml = 0x001b,
    Rust = 0x001c,
    C11 = 0x001d,
    Swift = 0x001e,
    Julia = 0x001f,
    Dylan = 0x0020,
    Cpp14 = 0x0021,
    Fortran03 = 0x0022,
    Fortran08 = 0x0023,
    RenderScript = 0x0024,
    BLISS = 0x0025,
    Kotlin = 0x0026,
    Zig = 0x0027,
    Crystal = 0x0028,
    Cpp17 = 0x002a,
    Cpp20 = 0x002b,
    C17 = 0x002c,
    Fortran18 = 0x002d,
    Ada2005 = 0x002e,
    Ada2012 = 0x002f,
    HIP = 0x0030,
    Assembly = 0x0031,
    CSharp = 0x0032,
    Mojo = 0x0033,
    GLSL = 0x0034,
    GLSLES = 0x0035,
    HLSL = 0x0036,
    OpenCLCpp = 0x0037,
    CppForOpenCL = 0x0038,
    SYCL = 0x0039,
    Metal = 0x003d,
    Ruby = 0x0040,
    Move = 0x0041,
    Hylo = 0x0042,
}

/// DWARF type encoding values (`DW_ATE_*`)
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
#[non_exhaustive]
pub enum DwarfEncoding {
    #[default]
    None = 0x00,
    Address = 0x01,
    Boolean = 0x02,
    ComplexFloat = 0x03,
    Float = 0x04,
    Signed = 0x05,
    SignedChar = 0x06,
    Unsigned = 0x07,
    UnsignedChar = 0x08,
    ImaginaryFloat = 0x09,
    PackedDecimal = 0x0a,
    NumericString = 0x0b,
    Edited = 0x0c,
    SignedFixed = 0x0d,
    UnsignedFixed = 0x0e,
    DecimalFloat = 0x0f,
    UTF = 0x10,
    UCS = 0x11,
    ASCII = 0x12,
}

/// DWARF tag values (`DW_TAG_*`)
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u16)]
#[non_exhaustive]
pub enum DwarfTag {
    Null = 0x0000,
    ArrayType = 0x0001,
    ClassType = 0x0002,
    EntryPoint = 0x0003,
    EnumerationType = 0x0004,
    FormalParameter = 0x0005,
    ImportedDeclaration = 0x0008,
    Label = 0x000a,
    LexicalBlock = 0x000b,
    Member = 0x000d,
    PointerType = 0x000f,
    ReferenceType = 0x0010,
    CompileUnit = 0x0011,
    StringType = 0x0012,
    StructureType = 0x0013,
    SubroutineType = 0x0015,
    Typedef = 0x0016,
    UnionType = 0x0017,
    UnspecifiedParameters = 0x0018,
    Variant = 0x0019,
    CommonBlock = 0x001a,
    CommonInclusion = 0x001b,
    Inheritance = 0x001c,
    InlinedSubroutine = 0x001d,
    Module = 0x001e,
    PtrToMemberType = 0x001f,
    SetType = 0x0020,
    SubrangeType = 0x0021,
    WithStmt = 0x0022,
    AccessDeclaration = 0x0023,
    BaseType = 0x0024,
    CatchBlock = 0x0025,
    ConstType = 0x0026,
    Constant = 0x0027,
    Enumerator = 0x0028,
    FileType = 0x0029,
    Friend = 0x002a,
    Namelist = 0x002b,
    NamelistItem = 0x002c,
    PackedType = 0x002d,
    Subprogram = 0x002e,
    TemplateTypeParameter = 0x002f,
    TemplateValueParameter = 0x0030,
    ThrownType = 0x0031,
    TryBlock = 0x0032,
    VariantPart = 0x0033,
    Variable = 0x0034,
    VolatileType = 0x0035,
    DwarfProcedure = 0x0036,
    RestrictType = 0x0037,
    InterfaceType = 0x0038,
    Namespace = 0x0039,
    ImportedModule = 0x003a,
    UnspecifiedType = 0x003b,
    PartialUnit = 0x003c,
    ImportedUnit = 0x003d,
    Condition = 0x003f,
    SharedType = 0x0040,
    TypeUnit = 0x0041,
    RvalueReferenceType = 0x0042,
    TemplateAlias = 0x0043,
    CoarrayType = 0x0044,
    GenericSubrange = 0x0045,
    DynamicType = 0x0046,
    AtomicType = 0x0047,
    CallSite = 0x0048,
    CallSiteParameter = 0x0049,
    SkeletonUnit = 0x004a,
    ImmutableType = 0x004b,
}

// `DW_CC_*`
#[derive(Debug, Copy, Clone, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
#[non_exhaustive]
pub enum DwarfCallConv {
    Normal = 0x01,
    Program = 0x02,
    NoCall = 0x03,
    // New in DWARF v5:
    PassByReference = 0x04,
    PassByValue = 0x05,
    // Vendor extensions:
    GnuRenesasSh = 0x40,
    GnuBorlandFastcalli386 = 0x41,
    BorlandSafecall = 0xb0,
    BorlandStdcall = 0xb1,
    BorlandPascal = 0xb2,
    BorlandMsfastcall = 0xb3,
    BorlandMsreturn = 0xb4,
    BorlandThiscall = 0xb5,
    BorlandFastcall = 0xb6,
    LlvmVectorcall = 0xc0,
    LlvmWin64 = 0xc1,
    LlvmX8664SysV = 0xc2,
    LlvmAapcs = 0xc3,
    LlvmAapcsVfp = 0xc4,
    LlvmIntelOclBicc = 0xc5,
    LlvmSpirFunction = 0xc6,
    LlvmDeviceKernel = 0xc7,
    LlvmSwift = 0xc8,
    LlvmPreserveMost = 0xc9,
    LlvmPreserveAll = 0xca,
    LlvmX86RegCall = 0xcb,
    LlvmM68kRtd = 0xcc,
    LlvmPreserveNone = 0xcd,
    LlvmRiscVVectorCall = 0xce,
    LlvmSwiftTail = 0xcf,
    LlvmRiscVVlsCall = 0xd0,
}
