fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
    unsafe {
        let mut declared = HashSet::new();

        let iter_globals = |llmod| {
            ValueIter {
                cur: llvm::LLVMGetFirstGlobal(llmod),
                step: llvm::LLVMGetNextGlobal,
            }
        };

        let iter_functions = |llmod| {
            ValueIter {
                cur: llvm::LLVMGetFirstFunction(llmod),
                step: llvm::LLVMGetNextFunction,
            }
        };

        // Collect all external declarations in all compilation units.
        for ccx in cx.iter() {
            for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
                let linkage = llvm::LLVMGetLinkage(val);
                // We only care about external declarations (not definitions)
                // and available_externally definitions.
                if !(linkage == llvm::ExternalLinkage as c_uint &&
                     llvm::LLVMIsDeclaration(val) != 0) &&
                   !(linkage == llvm::AvailableExternallyLinkage as c_uint) {
                    continue
                }

                let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
                                .to_bytes().to_vec();
                declared.insert(name);
            }
        }

        // Examine each external definition.  If the definition is not used in
        // any other compilation unit, and is not reachable from other crates,
        // then give it internal linkage.
        for ccx in cx.iter() {
            for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
                // We only care about external definitions.
                if !(llvm::LLVMGetLinkage(val) == llvm::ExternalLinkage as c_uint &&
                     llvm::LLVMIsDeclaration(val) == 0) {
                    continue
                }

                let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
                                .to_bytes().to_vec();
                if !declared.contains(&name) &&
                   !reachable.contains(str::from_utf8(&name).unwrap()) {
                    llvm::SetLinkage(val, llvm::InternalLinkage);
                    llvm::SetDLLStorageClass(val, llvm::DefaultStorageClass);
                }
            }
        }
    }


    struct ValueIter {
        cur: ValueRef,
        step: unsafe extern "C" fn(ValueRef) -> ValueRef,
    }

    impl Iterator for ValueIter {
        type Item = ValueRef;

        fn next(&mut self) -> Option<ValueRef> {
            let old = self.cur;
            if !old.is_null() {
                self.cur = unsafe {
                    let step: unsafe extern "C" fn(ValueRef) -> ValueRef =
                        mem::transmute_copy(&self.step);
                    step(old)
                };
                Some(old)
            } else {
                None
            }
        }
    }
}
/// Find any symbols that are defined in one compilation unit, but not declared
/// in any other compilation unit.  Give these symbols internal linkage.
Find any symbols that are defined in one compilation unit, but not declared
in any other compilation unit.  Give these symbols internal linkage.
Find any symbols that are defined in one compilation unit but not declared in any other compilation unit . Give these symbols internal linkage .
fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
    unsafe {
        let mut declared = HashSet::new();
        let iter_globals = |llmod| {
            ValueIter {
                cur: llvm::LLVMGetFirstGlobal(llmod),
                step: llvm::LLVMGetNextGlobal,
            }
        };
        let iter_functions = |llmod| {
            ValueIter {
                cur: llvm::LLVMGetFirstFunction(llmod),
                step: llvm::LLVMGetNextFunction,
            }
        };
        // Collect all external declarations in all compilation units.
        for ccx in cx.iter() {
            for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
                let linkage = llvm::LLVMGetLinkage(val);
                // We only care about external declarations (not definitions)
                // and available_externally definitions.
                if !(linkage == llvm::ExternalLinkage as c_uint &&
                     llvm::LLVMIsDeclaration(val) != 0) &&
                   !(linkage == llvm::AvailableExternallyLinkage as c_uint) {
                    continue
                }
                let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
                                .to_bytes().to_vec();
                declared.insert(name);
            }
        }
        // Examine each external definition.  If the definition is not used in
        // any other compilation unit, and is not reachable from other crates,
        // then give it internal linkage.
        for ccx in cx.iter() {
            for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
                // We only care about external definitions.
                if !(llvm::LLVMGetLinkage(val) == llvm::ExternalLinkage as c_uint &&
                     llvm::LLVMIsDeclaration(val) == 0) {
                    continue
                }
                let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
                                .to_bytes().to_vec();
                if !declared.contains(&name) &&
                   !reachable.contains(str::from_utf8(&name).unwrap()) {
                    llvm::SetLinkage(val, llvm::InternalLinkage);
                    llvm::SetDLLStorageClass(val, llvm::DefaultStorageClass);
                }
            }
        }
    }
    struct ValueIter {
        cur: ValueRef,
        step: unsafe extern "C" fn(ValueRef) -> ValueRef,
    }
    impl Iterator for ValueIter {
        type Item = ValueRef;
        fn next(&mut self) -> Option<ValueRef> {
            let old = self.cur;
            if !old.is_null() {
                self.cur = unsafe {
                    let step: unsafe extern "C" fn(ValueRef) -> ValueRef =
                        mem::transmute_copy(&self.step);
                    step(old)
                };
                Some(old)
            } else {
                None
            }
        }
    }
}
fn internalize_symbols ( cx : & SharedCrateContext , reachable : & HashSet < & str > ) { unsafe { let mut declared = HashSet :: new ( ) ; let iter_globals = | llmod | { ValueIter { cur : llvm :: LLVMGetFirstGlobal ( llmod ) , step : llvm :: LLVMGetNextGlobal , } } ; let iter_functions = | llmod | { ValueIter { cur : llvm :: LLVMGetFirstFunction ( llmod ) , step : llvm :: LLVMGetNextFunction , } } ; // Collect all external declarations in all compilation units. for ccx in cx . iter ( ) { for val in iter_globals ( ccx . llmod ( ) ) . chain ( iter_functions ( ccx . llmod ( ) ) ) { let linkage = llvm :: LLVMGetLinkage ( val ) ; // We only care about external declarations (not definitions) // and available_externally definitions. if ! ( linkage == llvm :: ExternalLinkage as c_uint && llvm :: LLVMIsDeclaration ( val ) != 0 ) && ! ( linkage == llvm :: AvailableExternallyLinkage as c_uint ) { continue } let name = CStr :: from_ptr ( llvm :: LLVMGetValueName ( val ) ) . to_bytes ( ) . to_vec ( ) ; declared . insert ( name ) ; } } // Examine each external definition.  If the definition is not used in // any other compilation unit, and is not reachable from other crates, // then give it internal linkage. for ccx in cx . iter ( ) { for val in iter_globals ( ccx . llmod ( ) ) . chain ( iter_functions ( ccx . llmod ( ) ) ) { // We only care about external definitions. if ! ( llvm :: LLVMGetLinkage ( val ) == llvm :: ExternalLinkage as c_uint && llvm :: LLVMIsDeclaration ( val ) == 0 ) { continue } let name = CStr :: from_ptr ( llvm :: LLVMGetValueName ( val ) ) . to_bytes ( ) . to_vec ( ) ; if ! declared . contains ( & name ) && ! reachable . contains ( str :: from_utf8 ( & name ) . unwrap ( ) ) { llvm :: SetLinkage ( val , llvm :: InternalLinkage ) ; llvm :: SetDLLStorageClass ( val , llvm :: DefaultStorageClass ) ; } } } } struct ValueIter { cur : ValueRef , step : unsafe extern " " fn ( ValueRef ) -> ValueRef , } impl Iterator for ValueIter { type Item = ValueRef ; fn next ( & mut self ) -> Option < ValueRef > { let old = self . cur ; if ! old . is_null ( ) { self . cur = unsafe { let step : unsafe extern " " fn ( ValueRef ) -> ValueRef = mem :: transmute_copy ( & self . step ) ; step ( old ) } ; Some ( old ) } else { None } } } }
Find any symbols that are defined in one compilation unit, but not declared
in any other compilation unit.
Find any symbols that are defined in one compilation unit but not declared in any other compilation unit .
cx
&SharedCrateContext
reachable
&HashSet<&str>
cx
&SharedCrateContext
reachable
&HashSet<&str>