<commit_before>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![allow(non_camel_case_types, non_snake_case_functions)]

//! Code that is useful in various trans modules.

use driver::session::Session;
use llvm;
use llvm::{ValueRef, BasicBlockRef, BuilderRef};
use llvm::{True, False, Bool};
use middle::def;
use middle::lang_items::LangItem;
use middle::subst;
use middle::subst::Subst;
use middle::trans::build;
use middle::trans::cleanup;
use middle::trans::datum;
use middle::trans::debuginfo;
use middle::trans::type_::Type;
use middle::ty;
use middle::typeck;
use util::ppaux::Repr;
use util::nodemap::NodeMap;

use arena::TypedArena;
use std::collections::HashMap;
use libc::{c_uint, c_longlong, c_ulonglong, c_char};
use std::c_str::ToCStr;
use std::cell::{Cell, RefCell};
use std::vec::Vec;
use syntax::ast::Ident;
use syntax::ast;
use syntax::ast_map::{PathElem, PathName};
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::parse::token;

pub use middle::trans::context::CrateContext;

fn type_is_newtype_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
    match ty::get(ty).sty {
        ty::ty_struct(def_id, ref substs) => {
            let fields = ty::struct_fields(ccx.tcx(), def_id, substs);
            fields.len() == 1 &&
                fields.get(0).ident.name ==
                    token::special_idents::unnamed_field.name &&
                type_is_immediate(ccx, fields.get(0).mt.ty)
        }
        _ => false
    }
}

pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
    use middle::trans::machine::llsize_of_alloc;
    use middle::trans::type_of::sizing_type_of;
    let tcx = ccx.tcx();
    let simple = ty::type_is_scalar(ty) || ty::type_is_boxed(ty) ||
        ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
        type_is_newtype_immediate(ccx, ty) || ty::type_is_bot(ty) ||
        ty::type_is_simd(tcx, ty);
    if simple && !ty::type_is_trait(ty) {
        return true;
    }
    match ty::get(ty).sty {
        ty::ty_bot => true,
        ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) |
        ty::ty_unboxed_closure(..) => {
            let llty = sizing_type_of(ccx, ty);
            llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type)
        }
        _ => type_is_zero_size(ccx, ty)
    }
}

pub fn type_is_zero_size(ccx: &CrateContext, ty: ty::t) -> bool {
    /*!
     * Identify types which have size zero at runtime.
     */

    use middle::trans::machine::llsize_of_alloc;
    use middle::trans::type_of::sizing_type_of;
    let llty = sizing_type_of(ccx, ty);
    llsize_of_alloc(ccx, llty) == 0
}

pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
    /*!
     * Identifies types which we declare to be equivalent to `void`
     * in C for the purpose of function return types. These are
     * `()`, bot, and uninhabited enums. Note that all such types
     * are also zero-size, but not all zero-size types use a `void`
     * return type (in order to aid with C ABI compatibility).
     */

    ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx(), ty)
}

/// Generates a unique symbol based off the name given. This is used to create
/// unique symbols for things like closures.
pub fn gensym_name(name: &str) -> PathElem {
    let num = token::gensym(name);
    // use one colon which will get translated to a period by the mangler, and
    // we're guaranteed that `num` is globally unique for this crate.
    PathName(token::gensym(format!("{}:{}", name, num).as_slice()))
}

pub struct tydesc_info {
    pub ty: ty::t,
    pub tydesc: ValueRef,
    pub size: ValueRef,<commit_msg>Stop using the Show impl for ast::Name in our symbols<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![allow(non_camel_case_types, non_snake_case_functions)]

//! Code that is useful in various trans modules.

use driver::session::Session;
use llvm;
use llvm::{ValueRef, BasicBlockRef, BuilderRef};
use llvm::{True, False, Bool};
use middle::def;
use middle::lang_items::LangItem;
use middle::subst;
use middle::subst::Subst;
use middle::trans::build;
use middle::trans::cleanup;
use middle::trans::datum;
use middle::trans::debuginfo;
use middle::trans::type_::Type;
use middle::ty;
use middle::typeck;
use util::ppaux::Repr;
use util::nodemap::NodeMap;

use arena::TypedArena;
use std::collections::HashMap;
use libc::{c_uint, c_longlong, c_ulonglong, c_char};
use std::c_str::ToCStr;
use std::cell::{Cell, RefCell};
use std::vec::Vec;
use syntax::ast::Ident;
use syntax::ast;
use syntax::ast_map::{PathElem, PathName};
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::parse::token;

pub use middle::trans::context::CrateContext;

fn type_is_newtype_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
    match ty::get(ty).sty {
        ty::ty_struct(def_id, ref substs) => {
            let fields = ty::struct_fields(ccx.tcx(), def_id, substs);
            fields.len() == 1 &&
                fields.get(0).ident.name ==
                    token::special_idents::unnamed_field.name &&
                type_is_immediate(ccx, fields.get(0).mt.ty)
        }
        _ => false
    }
}

pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
    use middle::trans::machine::llsize_of_alloc;
    use middle::trans::type_of::sizing_type_of;
    let tcx = ccx.tcx();
    let simple = ty::type_is_scalar(ty) || ty::type_is_boxed(ty) ||
        ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
        type_is_newtype_immediate(ccx, ty) || ty::type_is_bot(ty) ||
        ty::type_is_simd(tcx, ty);
    if simple && !ty::type_is_trait(ty) {
        return true;
    }
    match ty::get(ty).sty {
        ty::ty_bot => true,
        ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) |
        ty::ty_unboxed_closure(..) => {
            let llty = sizing_type_of(ccx, ty);
            llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type)
        }
        _ => type_is_zero_size(ccx, ty)
    }
}

pub fn type_is_zero_size(ccx: &CrateContext, ty: ty::t) -> bool {
    /*!
     * Identify types which have size zero at runtime.
     */

    use middle::trans::machine::llsize_of_alloc;
    use middle::trans::type_of::sizing_type_of;
    let llty = sizing_type_of(ccx, ty);
    llsize_of_alloc(ccx, llty) == 0
}

pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
    /*!
     * Identifies types which we declare to be equivalent to `void`
     * in C for the purpose of function return types. These are
     * `()`, bot, and uninhabited enums. Note that all such types
     * are also zero-size, but not all zero-size types use a `void`
     * return type (in order to aid with C ABI compatibility).
     */

    ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx(), ty)
}

/// Generates a unique symbol based off the name given. This is used to create
/// unique symbols for things like closures.
pub fn gensym_name(name: &str) -> PathElem {
    let num = token::gensym(name).uint();
    // use one colon which will get translated to a period by the mangler, and
    // we're guaranteed that `num` is globally unique for this crate.
    PathName(token::gensym(format!("{}:{}", name, num).as_slice()))
}

pub struct tydesc_info {
    pub ty: ty::t,
    pub tydesc: ValueRef,
    pub size: ValueRef,
{'fraction_non_alphanumeric': 0.14706240116774116, 'fraction_numerical': 0.003892470502371974, 'mean_word_length': 3.6165075800112296, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6942165', 'n_tokens_mistral': 2852, 'n_tokens_neox': 2835, 'n_words': 730}