lldb 0.0.11

Rust-like bindings to the public LLDB API. LLDB is the debugger from the LLVM project and is the system debugger on macOS.
Documentation
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use crate::{sys, BasicType, DescriptionLevel, SBModule, SBStream, TypeClass};
use std::ffi::CStr;
use std::fmt;

#[allow(missing_docs)]
pub struct SBType {
    /// The underlying raw `SBTypeRef`.
    pub raw: sys::SBTypeRef,
}

impl SBType {
    /// Construct a new `SBType`.
    pub(crate) fn wrap(raw: sys::SBTypeRef) -> SBType {
        SBType { raw }
    }

    /// Construct a new `Some(SBType)` or `None`.
    pub(crate) fn maybe_wrap(raw: sys::SBTypeRef) -> Option<SBType> {
        if unsafe { sys::SBTypeIsValid(raw) } {
            Some(SBType { raw })
        } else {
            None
        }
    }

    /// Check whether or not this is a valid `SBType` value.
    pub fn is_valid(&self) -> bool {
        unsafe { sys::SBTypeIsValid(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_pointer_type(&self) -> bool {
        unsafe { sys::SBTypeIsPointerType(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_reference_type(&self) -> bool {
        unsafe { sys::SBTypeIsReferenceType(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_function_type(&self) -> bool {
        unsafe { sys::SBTypeIsFunctionType(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_polymorphic_class(&self) -> bool {
        unsafe { sys::SBTypeIsPolymorphicClass(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_array_type(&self) -> bool {
        unsafe { sys::SBTypeIsArrayType(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_vector_type(&self) -> bool {
        unsafe { sys::SBTypeIsVectorType(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_typedef_type(&self) -> bool {
        unsafe { sys::SBTypeIsTypedefType(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_anonymous_type(&self) -> bool {
        unsafe { sys::SBTypeIsAnonymousType(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn is_scoped_enumeration_type(&self) -> bool {
        unsafe { sys::SBTypeIsScopedEnumerationType(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn pointer_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetPointerType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn pointee_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetPointeeType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn reference_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetReferenceType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn typedefed_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetTypedefedType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn dereferenced_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetDereferencedType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn unqualified_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetUnqualifiedType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn array_element_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetArrayElementType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn vector_element_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetVectorElementType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn canonical_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetCanonicalType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn enumeration_integer_type(&self) -> Option<SBType> {
        SBType::maybe_wrap(unsafe { sys::SBTypeGetEnumerationIntegerType(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn basic_type(&self) -> BasicType {
        unsafe { sys::SBTypeGetBasicType(self.raw) }
    }

    /// Returns the [`SBModule`] this type belongs to.
    ///
    /// Returns `None` if this type does not belong to any specific
    /// [`SBModule`] or this type is invalid. An invalid module might also
    /// indicate that once came from a module but LLDB could no longer
    /// determine the original module.
    pub fn module(&self) -> Option<SBModule> {
        SBModule::maybe_wrap(unsafe { sys::SBTypeGetModule(self.raw) })
    }

    #[allow(missing_docs)]
    pub fn name(&self) -> &str {
        unsafe {
            match CStr::from_ptr(sys::SBTypeGetName(self.raw)).to_str() {
                Ok(s) => s,
                _ => panic!("Invalid string?"),
            }
        }
    }

    #[allow(missing_docs)]
    pub fn display_type_name(&self) -> &str {
        unsafe {
            match CStr::from_ptr(sys::SBTypeGetDisplayTypeName(self.raw)).to_str() {
                Ok(s) => s,
                _ => panic!("Invalid string?"),
            }
        }
    }

    #[allow(missing_docs)]
    pub fn type_class(&self) -> TypeClass {
        TypeClass::from_bits_truncate(unsafe { sys::SBTypeGetTypeClass(self.raw) })
    }
}

impl Clone for SBType {
    fn clone(&self) -> SBType {
        SBType {
            raw: unsafe { sys::CloneSBType(self.raw) },
        }
    }
}

impl fmt::Debug for SBType {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let stream = SBStream::new();
        unsafe { sys::SBTypeGetDescription(self.raw, stream.raw, DescriptionLevel::Brief) };
        write!(fmt, "SBType {{ {} }}", stream.data())
    }
}

impl Drop for SBType {
    fn drop(&mut self) {
        unsafe { sys::DisposeSBType(self.raw) };
    }
}

unsafe impl Send for SBType {}
unsafe impl Sync for SBType {}

#[cfg(feature = "graphql")]
#[graphql_object]
impl SBType {
    fn is_pointer_type() -> bool {
        self.is_pointer_type()
    }

    fn is_reference_type() -> bool {
        self.is_reference_type()
    }

    fn is_function_type() -> bool {
        self.is_function_type()
    }

    fn is_polymorphic_class() -> bool {
        self.is_polymorphic_class()
    }

    fn is_array_type() -> bool {
        self.is_array_type()
    }

    fn is_vector_type() -> bool {
        self.is_vector_type()
    }

    fn is_typedef_type() -> bool {
        self.is_typedef_type()
    }

    fn pointer_type() -> Option<SBType> {
        self.pointer_type()
    }

    fn pointee_type() -> Option<SBType> {
        self.pointee_type()
    }

    fn reference_type() -> Option<SBType> {
        self.reference_type()
    }

    fn typedefed_type() -> Option<SBType> {
        self.typedefed_type()
    }

    fn dereferenced_type() -> Option<SBType> {
        self.dereferenced_type()
    }

    fn unqualified_type() -> Option<SBType> {
        self.unqualified_type()
    }

    fn array_element_type() -> Option<SBType> {
        self.array_element_type()
    }

    fn vector_element_type() -> Option<SBType> {
        self.vector_element_type()
    }

    fn canonical_type() -> Option<SBType> {
        self.canonical_type()
    }

    // TODO(bm) bind `basic_type`.

    fn name() -> &str {
        self.name()
    }
}