@@ -34,14 +34,21 @@ 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 ast_map;
37
38
use log;
38
39
40
+ pub struct LocalCrateReader < ' a , ' b : ' a > {
41
+ sess : & ' a Session ,
42
+ creader : CrateReader < ' a > ,
43
+ ast_map : & ' a ast_map:: Map < ' b > ,
44
+ }
45
+
39
46
pub struct CrateReader < ' a > {
40
47
sess : & ' a Session ,
41
48
next_crate_num : ast:: CrateNum ,
42
49
}
43
50
44
- impl < ' a , ' v > visit:: Visitor < ' v > for CrateReader < ' a > {
51
+ impl < ' a , ' b , ' v > visit:: Visitor < ' v > for LocalCrateReader < ' a , ' b > {
45
52
fn visit_item ( & mut self , a : & ast:: Item ) {
46
53
self . process_item ( a) ;
47
54
visit:: walk_item ( self , a) ;
@@ -152,31 +159,6 @@ impl<'a> CrateReader<'a> {
152
159
}
153
160
}
154
161
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
162
fn extract_crate_info ( & self , i : & ast:: Item ) -> Option < CrateInfo > {
181
163
match i. node {
182
164
ast:: ItemExternCrate ( ref path_opt) => {
@@ -201,103 +183,6 @@ impl<'a> CrateReader<'a> {
201
183
}
202
184
}
203
185
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
186
fn existing_match ( & self , name : & str , hash : Option < & Svh > , kind : PathKind )
302
187
-> Option < ast:: CrateNum > {
303
188
let mut ret = None ;
@@ -592,6 +477,138 @@ impl<'a> CrateReader<'a> {
592
477
}
593
478
}
594
479
480
+ impl < ' a , ' b > LocalCrateReader < ' a , ' b > {
481
+ pub fn new ( sess : & ' a Session , map : & ' a ast_map:: Map < ' b > ) -> LocalCrateReader < ' a , ' b > {
482
+ LocalCrateReader {
483
+ sess : sess,
484
+ creader : CrateReader :: new ( sess) ,
485
+ ast_map : map,
486
+ }
487
+ }
488
+
489
+ // Traverses an AST, reading all the information about use'd crates and
490
+ // extern libraries necessary for later resolving, typechecking, linking,
491
+ // etc.
492
+ pub fn read_crates ( & mut self , krate : & ast:: Crate ) {
493
+ self . process_crate ( krate) ;
494
+ visit:: walk_crate ( self , krate) ;
495
+
496
+ if log_enabled ! ( log:: DEBUG ) {
497
+ dump_crates ( & self . sess . cstore ) ;
498
+ }
499
+
500
+ for & ( ref name, kind) in & self . sess . opts . libs {
501
+ register_native_lib ( self . sess , None , name. clone ( ) , kind) ;
502
+ }
503
+ }
504
+
505
+ fn process_crate ( & self , c : & ast:: Crate ) {
506
+ for a in c. attrs . iter ( ) . filter ( |m| m. name ( ) == "link_args" ) {
507
+ match a. value_str ( ) {
508
+ Some ( ref linkarg) => self . sess . cstore . add_used_link_args ( & linkarg) ,
509
+ None => { /* fallthrough */ }
510
+ }
511
+ }
512
+ }
513
+
514
+ fn process_item ( & mut self , i : & ast:: Item ) {
515
+ match i. node {
516
+ ast:: ItemExternCrate ( _) => {
517
+ if !should_link ( i) {
518
+ return ;
519
+ }
520
+
521
+ match self . creader . extract_crate_info ( i) {
522
+ Some ( info) => {
523
+ let ( cnum, _, _) = self . creader . resolve_crate ( & None ,
524
+ & info. ident ,
525
+ & info. name ,
526
+ None ,
527
+ i. span ,
528
+ PathKind :: Crate ) ;
529
+ self . sess . cstore . add_extern_mod_stmt_cnum ( info. id , cnum) ;
530
+ }
531
+ None => ( )
532
+ }
533
+ }
534
+ ast:: ItemForeignMod ( ref fm) => {
535
+ if fm. abi == abi:: Rust || fm. abi == abi:: RustIntrinsic {
536
+ return ;
537
+ }
538
+
539
+ // First, add all of the custom link_args attributes
540
+ let link_args = i. attrs . iter ( )
541
+ . filter_map ( |at| if at. name ( ) == "link_args" {
542
+ Some ( at)
543
+ } else {
544
+ None
545
+ } )
546
+ . collect :: < Vec < & ast:: Attribute > > ( ) ;
547
+ for m in & link_args {
548
+ match m. value_str ( ) {
549
+ Some ( linkarg) => self . sess . cstore . add_used_link_args ( & linkarg) ,
550
+ None => { /* fallthrough */ }
551
+ }
552
+ }
553
+
554
+ // Next, process all of the #[link(..)]-style arguments
555
+ let link_args = i. attrs . iter ( )
556
+ . filter_map ( |at| if at. name ( ) == "link" {
557
+ Some ( at)
558
+ } else {
559
+ None
560
+ } )
561
+ . collect :: < Vec < & ast:: Attribute > > ( ) ;
562
+ for m in & link_args {
563
+ match m. meta_item_list ( ) {
564
+ Some ( items) => {
565
+ let kind = items. iter ( ) . find ( |k| {
566
+ k. name ( ) == "kind"
567
+ } ) . and_then ( |a| a. value_str ( ) ) ;
568
+ let kind = match kind {
569
+ Some ( k) => {
570
+ if k == "static" {
571
+ cstore:: NativeStatic
572
+ } else if self . sess . target . target . options . is_like_osx
573
+ && k == "framework" {
574
+ cstore:: NativeFramework
575
+ } else if k == "framework" {
576
+ cstore:: NativeFramework
577
+ } else if k == "dylib" {
578
+ cstore:: NativeUnknown
579
+ } else {
580
+ self . sess . span_err ( m. span ,
581
+ & format ! ( "unknown kind: `{}`" ,
582
+ k) ) ;
583
+ cstore:: NativeUnknown
584
+ }
585
+ }
586
+ None => cstore:: NativeUnknown
587
+ } ;
588
+ let n = items. iter ( ) . find ( |n| {
589
+ n. name ( ) == "name"
590
+ } ) . and_then ( |a| a. value_str ( ) ) ;
591
+ let n = match n {
592
+ Some ( n) => n,
593
+ None => {
594
+ self . sess . span_err ( m. span ,
595
+ "#[link(...)] specified without \
596
+ `name = \" foo\" `") ;
597
+ InternedString :: new ( "foo" )
598
+ }
599
+ } ;
600
+ register_native_lib ( self . sess , Some ( m. span ) ,
601
+ n. to_string ( ) , kind) ;
602
+ }
603
+ None => { }
604
+ }
605
+ }
606
+ }
607
+ _ => { }
608
+ }
609
+ }
610
+ }
611
+
595
612
/// Imports the codemap from an external crate into the codemap of the crate
596
613
/// currently being compiled (the "local crate").
597
614
///
0 commit comments