@@ -34,14 +34,22 @@ use syntax::codemap::{self, Span, mk_sp, Pos};
34
34
use syntax:: parse;
35
35
use syntax:: parse:: token:: InternedString ;
36
36
use syntax:: visit;
37
+ use syntax:: util:: small_vector:: SmallVector ;
38
+ use ast_map;
37
39
use log;
38
40
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
+
39
47
pub struct CrateReader < ' a > {
40
48
sess : & ' a Session ,
41
49
next_crate_num : ast:: CrateNum ,
42
50
}
43
51
44
- impl < ' a , ' v > visit:: Visitor < ' v > for CrateReader < ' a > {
52
+ impl < ' a , ' b , ' v > visit:: Visitor < ' v > for LocalCrateReader < ' a , ' b > {
45
53
fn visit_item ( & mut self , a : & ast:: Item ) {
46
54
self . process_item ( a) ;
47
55
visit:: walk_item ( self , a) ;
@@ -152,31 +160,6 @@ impl<'a> CrateReader<'a> {
152
160
}
153
161
}
154
162
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
-
180
163
fn extract_crate_info ( & self , i : & ast:: Item ) -> Option < CrateInfo > {
181
164
match i. node {
182
165
ast:: ItemExternCrate ( ref path_opt) => {
@@ -201,103 +184,6 @@ impl<'a> CrateReader<'a> {
201
184
}
202
185
}
203
186
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
-
301
187
fn existing_match ( & self , name : & str , hash : Option < & Svh > , kind : PathKind )
302
188
-> Option < ast:: CrateNum > {
303
189
let mut ret = None ;
@@ -378,6 +264,7 @@ impl<'a> CrateReader<'a> {
378
264
379
265
let cmeta = Rc :: new ( cstore:: crate_metadata {
380
266
name : name. to_string ( ) ,
267
+ local_path : RefCell :: new ( SmallVector :: zero ( ) ) ,
381
268
data : metadata,
382
269
cnum_map : cnum_map,
383
270
cnum : cnum,
@@ -592,6 +479,140 @@ impl<'a> CrateReader<'a> {
592
479
}
593
480
}
594
481
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
+
595
616
/// Imports the codemap from an external crate into the codemap of the crate
596
617
/// currently being compiled (the "local crate").
597
618
///
0 commit comments