55 lines
1.7 KiB
Rust
55 lines
1.7 KiB
Rust
use rustc_hir as hir;
|
|
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
|
use rustc_middle::ty::TyCtxt;
|
|
use rustc_span::symbol::{sym, Symbol};
|
|
use rustc_target::spec::abi::Abi;
|
|
|
|
crate fn collect(tcx: TyCtxt<'_>) -> Vec<String> {
|
|
let mut collector = Collector { tcx, args: Vec::new() };
|
|
tcx.hir().krate().visit_all_item_likes(&mut collector);
|
|
|
|
for attr in tcx.hir().attrs(hir::CRATE_HIR_ID).iter() {
|
|
if attr.has_name(sym::link_args) {
|
|
if let Some(linkarg) = attr.value_str() {
|
|
collector.add_link_args(linkarg);
|
|
}
|
|
}
|
|
}
|
|
|
|
collector.args
|
|
}
|
|
|
|
struct Collector<'tcx> {
|
|
tcx: TyCtxt<'tcx>,
|
|
args: Vec<String>,
|
|
}
|
|
|
|
impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
|
|
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
|
|
let abi = match it.kind {
|
|
hir::ItemKind::ForeignMod { abi, .. } => abi,
|
|
_ => return,
|
|
};
|
|
if abi == Abi::Rust || abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
|
|
return;
|
|
}
|
|
|
|
// First, add all of the custom #[link_args] attributes
|
|
let sess = &self.tcx.sess;
|
|
for m in it.attrs.iter().filter(|a| sess.check_name(a, sym::link_args)) {
|
|
if let Some(linkarg) = m.value_str() {
|
|
self.add_link_args(linkarg);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {}
|
|
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
|
|
fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {}
|
|
}
|
|
|
|
impl<'tcx> Collector<'tcx> {
|
|
fn add_link_args(&mut self, args: Symbol) {
|
|
self.args.extend(args.as_str().split(' ').filter(|s| !s.is_empty()).map(|s| s.to_string()))
|
|
}
|
|
}
|