@@ -34,14 +34,22 @@ use syntax::codemap::{self, Span, mk_sp, Pos};
3434use syntax:: parse;
3535use syntax:: parse:: token:: InternedString ;
3636use syntax:: visit;
37+ use syntax:: util:: small_vector:: SmallVector ;
38+ use ast_map;
3739use log;
3840
41+ pub struct LocalCrateReader < ' a , ' b : ' a > {
42+ sess : & ' a Session ,
43+ creader : CrateReader < ' a > ,
44+ ast_map : & ' a ast_map:: Map < ' b > ,
45+ }
46+
3947pub struct CrateReader < ' a > {
4048 sess : & ' a Session ,
4149 next_crate_num : ast:: CrateNum ,
4250}
4351
44- impl < ' a , ' v > visit:: Visitor < ' v > for CrateReader < ' a > {
52+ impl < ' a , ' b , ' v > visit:: Visitor < ' v > for LocalCrateReader < ' a , ' b > {
4553 fn visit_item ( & mut self , a : & ast:: Item ) {
4654 self . process_item ( a) ;
4755 visit:: walk_item ( self , a) ;
@@ -152,31 +160,6 @@ impl<'a> CrateReader<'a> {
152160 }
153161 }
154162
155- // Traverses an AST, reading all the information about use'd crates and
156- // extern libraries necessary for later resolving, typechecking, linking,
157- // etc.
158- pub fn read_crates ( & mut self , krate : & ast:: Crate ) {
159- self . process_crate ( krate) ;
160- visit:: walk_crate ( self , krate) ;
161-
162- if log_enabled ! ( log:: DEBUG ) {
163- dump_crates ( & self . sess . cstore ) ;
164- }
165-
166- for & ( ref name, kind) in & self . sess . opts . libs {
167- register_native_lib ( self . sess , None , name. clone ( ) , kind) ;
168- }
169- }
170-
171- fn process_crate ( & self , c : & ast:: Crate ) {
172- for a in c. attrs . iter ( ) . filter ( |m| m. name ( ) == "link_args" ) {
173- match a. value_str ( ) {
174- Some ( ref linkarg) => self . sess . cstore . add_used_link_args ( & linkarg) ,
175- None => { /* fallthrough */ }
176- }
177- }
178- }
179-
180163 fn extract_crate_info ( & self , i : & ast:: Item ) -> Option < CrateInfo > {
181164 match i. node {
182165 ast:: ItemExternCrate ( ref path_opt) => {
@@ -201,103 +184,6 @@ impl<'a> CrateReader<'a> {
201184 }
202185 }
203186
204- fn process_item ( & mut self , i : & ast:: Item ) {
205- match i. node {
206- ast:: ItemExternCrate ( _) => {
207- if !should_link ( i) {
208- return ;
209- }
210-
211- match self . extract_crate_info ( i) {
212- Some ( info) => {
213- let ( cnum, _, _) = self . resolve_crate ( & None ,
214- & info. ident ,
215- & info. name ,
216- None ,
217- i. span ,
218- PathKind :: Crate ) ;
219- self . sess . cstore . add_extern_mod_stmt_cnum ( info. id , cnum) ;
220- }
221- None => ( )
222- }
223- }
224- ast:: ItemForeignMod ( ref fm) => {
225- if fm. abi == abi:: Rust || fm. abi == abi:: RustIntrinsic {
226- return ;
227- }
228-
229- // First, add all of the custom link_args attributes
230- let link_args = i. attrs . iter ( )
231- . filter_map ( |at| if at. name ( ) == "link_args" {
232- Some ( at)
233- } else {
234- None
235- } )
236- . collect :: < Vec < & ast:: Attribute > > ( ) ;
237- for m in & link_args {
238- match m. value_str ( ) {
239- Some ( linkarg) => self . sess . cstore . add_used_link_args ( & linkarg) ,
240- None => { /* fallthrough */ }
241- }
242- }
243-
244- // Next, process all of the #[link(..)]-style arguments
245- let link_args = i. attrs . iter ( )
246- . filter_map ( |at| if at. name ( ) == "link" {
247- Some ( at)
248- } else {
249- None
250- } )
251- . collect :: < Vec < & ast:: Attribute > > ( ) ;
252- for m in & link_args {
253- match m. meta_item_list ( ) {
254- Some ( items) => {
255- let kind = items. iter ( ) . find ( |k| {
256- k. name ( ) == "kind"
257- } ) . and_then ( |a| a. value_str ( ) ) ;
258- let kind = match kind {
259- Some ( k) => {
260- if k == "static" {
261- cstore:: NativeStatic
262- } else if self . sess . target . target . options . is_like_osx
263- && k == "framework" {
264- cstore:: NativeFramework
265- } else if k == "framework" {
266- cstore:: NativeFramework
267- } else if k == "dylib" {
268- cstore:: NativeUnknown
269- } else {
270- self . sess . span_err ( m. span ,
271- & format ! ( "unknown kind: `{}`" ,
272- k) ) ;
273- cstore:: NativeUnknown
274- }
275- }
276- None => cstore:: NativeUnknown
277- } ;
278- let n = items. iter ( ) . find ( |n| {
279- n. name ( ) == "name"
280- } ) . and_then ( |a| a. value_str ( ) ) ;
281- let n = match n {
282- Some ( n) => n,
283- None => {
284- self . sess . span_err ( m. span ,
285- "#[link(...)] specified without \
286- `name = \" foo\" `") ;
287- InternedString :: new ( "foo" )
288- }
289- } ;
290- register_native_lib ( self . sess , Some ( m. span ) ,
291- n. to_string ( ) , kind) ;
292- }
293- None => { }
294- }
295- }
296- }
297- _ => { }
298- }
299- }
300-
301187 fn existing_match ( & self , name : & str , hash : Option < & Svh > , kind : PathKind )
302188 -> Option < ast:: CrateNum > {
303189 let mut ret = None ;
@@ -378,6 +264,7 @@ impl<'a> CrateReader<'a> {
378264
379265 let cmeta = Rc :: new ( cstore:: crate_metadata {
380266 name : name. to_string ( ) ,
267+ local_path : RefCell :: new ( SmallVector :: zero ( ) ) ,
381268 data : metadata,
382269 cnum_map : cnum_map,
383270 cnum : cnum,
@@ -592,6 +479,140 @@ impl<'a> CrateReader<'a> {
592479 }
593480}
594481
482+ impl < ' a , ' b > LocalCrateReader < ' a , ' b > {
483+ pub fn new ( sess : & ' a Session , map : & ' a ast_map:: Map < ' b > ) -> LocalCrateReader < ' a , ' b > {
484+ LocalCrateReader {
485+ sess : sess,
486+ creader : CrateReader :: new ( sess) ,
487+ ast_map : map,
488+ }
489+ }
490+
491+ // Traverses an AST, reading all the information about use'd crates and
492+ // extern libraries necessary for later resolving, typechecking, linking,
493+ // etc.
494+ pub fn read_crates ( & mut self , krate : & ast:: Crate ) {
495+ self . process_crate ( krate) ;
496+ visit:: walk_crate ( self , krate) ;
497+
498+ if log_enabled ! ( log:: DEBUG ) {
499+ dump_crates ( & self . sess . cstore ) ;
500+ }
501+
502+ for & ( ref name, kind) in & self . sess . opts . libs {
503+ register_native_lib ( self . sess , None , name. clone ( ) , kind) ;
504+ }
505+ }
506+
507+ fn process_crate ( & self , c : & ast:: Crate ) {
508+ for a in c. attrs . iter ( ) . filter ( |m| m. name ( ) == "link_args" ) {
509+ match a. value_str ( ) {
510+ Some ( ref linkarg) => self . sess . cstore . add_used_link_args ( & linkarg) ,
511+ None => { /* fallthrough */ }
512+ }
513+ }
514+ }
515+
516+ fn process_item ( & mut self , i : & ast:: Item ) {
517+ match i. node {
518+ ast:: ItemExternCrate ( _) => {
519+ if !should_link ( i) {
520+ return ;
521+ }
522+
523+ match self . creader . extract_crate_info ( i) {
524+ Some ( info) => {
525+ let ( cnum, cmeta, _) = self . creader . resolve_crate ( & None ,
526+ & info. ident ,
527+ & info. name ,
528+ None ,
529+ i. span ,
530+ PathKind :: Crate ) ;
531+ self . ast_map . with_path ( i. id , |path|
532+ cmeta. update_local_path ( path) ) ;
533+ self . sess . cstore . add_extern_mod_stmt_cnum ( info. id , cnum) ;
534+ }
535+ None => ( )
536+ }
537+ }
538+ ast:: ItemForeignMod ( ref fm) => {
539+ if fm. abi == abi:: Rust || fm. abi == abi:: RustIntrinsic {
540+ return ;
541+ }
542+
543+ // First, add all of the custom link_args attributes
544+ let link_args = i. attrs . iter ( )
545+ . filter_map ( |at| if at. name ( ) == "link_args" {
546+ Some ( at)
547+ } else {
548+ None
549+ } )
550+ . collect :: < Vec < & ast:: Attribute > > ( ) ;
551+ for m in & link_args {
552+ match m. value_str ( ) {
553+ Some ( linkarg) => self . sess . cstore . add_used_link_args ( & linkarg) ,
554+ None => { /* fallthrough */ }
555+ }
556+ }
557+
558+ // Next, process all of the #[link(..)]-style arguments
559+ let link_args = i. attrs . iter ( )
560+ . filter_map ( |at| if at. name ( ) == "link" {
561+ Some ( at)
562+ } else {
563+ None
564+ } )
565+ . collect :: < Vec < & ast:: Attribute > > ( ) ;
566+ for m in & link_args {
567+ match m. meta_item_list ( ) {
568+ Some ( items) => {
569+ let kind = items. iter ( ) . find ( |k| {
570+ k. name ( ) == "kind"
571+ } ) . and_then ( |a| a. value_str ( ) ) ;
572+ let kind = match kind {
573+ Some ( k) => {
574+ if k == "static" {
575+ cstore:: NativeStatic
576+ } else if self . sess . target . target . options . is_like_osx
577+ && k == "framework" {
578+ cstore:: NativeFramework
579+ } else if k == "framework" {
580+ cstore:: NativeFramework
581+ } else if k == "dylib" {
582+ cstore:: NativeUnknown
583+ } else {
584+ self . sess . span_err ( m. span ,
585+ & format ! ( "unknown kind: `{}`" ,
586+ k) ) ;
587+ cstore:: NativeUnknown
588+ }
589+ }
590+ None => cstore:: NativeUnknown
591+ } ;
592+ let n = items. iter ( ) . find ( |n| {
593+ n. name ( ) == "name"
594+ } ) . and_then ( |a| a. value_str ( ) ) ;
595+ let n = match n {
596+ Some ( n) => n,
597+ None => {
598+ self . sess . span_err ( m. span ,
599+ "#[link(...)] specified without \
600+ `name = \" foo\" `") ;
601+ InternedString :: new ( "foo" )
602+ }
603+ } ;
604+ register_native_lib ( self . sess , Some ( m. span ) ,
605+ n. to_string ( ) , kind) ;
606+ }
607+ None => { }
608+ }
609+ }
610+ }
611+ _ => { }
612+ }
613+ }
614+ }
615+
595616/// Imports the codemap from an external crate into the codemap of the crate
596617/// currently being compiled (the "local crate").
597618///
0 commit comments