@@ -33,10 +33,11 @@ use syntax::feature_gate::AttributeType;
33
33
use syntax_pos:: { Span , MultiSpan } ;
34
34
35
35
use rustc_back:: target:: Target ;
36
+ use rustc_data_structures:: flock;
36
37
use llvm;
37
38
38
39
use std:: path:: { Path , PathBuf } ;
39
- use std:: cell:: { Cell , RefCell } ;
40
+ use std:: cell:: { self , Cell , RefCell } ;
40
41
use std:: collections:: { HashMap , HashSet } ;
41
42
use std:: env;
42
43
use std:: ffi:: CString ;
@@ -101,6 +102,8 @@ pub struct Session {
101
102
/// macro name and defintion span in the source crate.
102
103
pub imported_macro_spans : RefCell < HashMap < Span , ( String , Span ) > > ,
103
104
105
+ incr_comp_session : RefCell < IncrCompSession > ,
106
+
104
107
next_node_id : Cell < ast:: NodeId > ,
105
108
}
106
109
@@ -331,6 +334,70 @@ impl Session {
331
334
& self . opts . search_paths ,
332
335
kind)
333
336
}
337
+
338
+ pub fn init_incr_comp_session ( & self ,
339
+ session_dir : PathBuf ,
340
+ lock_file : flock:: Lock ) {
341
+ let mut incr_comp_session = self . incr_comp_session . borrow_mut ( ) ;
342
+
343
+ if let IncrCompSession :: NotInitialized = * incr_comp_session { } else {
344
+ bug ! ( "Trying to initialize IncrCompSession `{:?}`" , * incr_comp_session)
345
+ }
346
+
347
+ * incr_comp_session = IncrCompSession :: Active {
348
+ session_directory : session_dir,
349
+ lock_file : lock_file,
350
+ } ;
351
+ }
352
+
353
+ pub fn finalize_incr_comp_session ( & self , new_directory_path : PathBuf ) {
354
+ let mut incr_comp_session = self . incr_comp_session . borrow_mut ( ) ;
355
+
356
+ if let IncrCompSession :: Active { .. } = * incr_comp_session { } else {
357
+ bug ! ( "Trying to finalize IncrCompSession `{:?}`" , * incr_comp_session)
358
+ }
359
+
360
+ // Note: This will also drop the lock file, thus unlocking the directory
361
+ * incr_comp_session = IncrCompSession :: Finalized {
362
+ session_directory : new_directory_path,
363
+ } ;
364
+ }
365
+
366
+ pub fn mark_incr_comp_session_as_invalid ( & self ) {
367
+ let mut incr_comp_session = self . incr_comp_session . borrow_mut ( ) ;
368
+
369
+ if let IncrCompSession :: Active { .. } = * incr_comp_session { } else {
370
+ bug ! ( "Trying to invalidate IncrCompSession `{:?}`" , * incr_comp_session)
371
+ }
372
+
373
+ // Note: This will also drop the lock file, thus unlocking the directory
374
+ * incr_comp_session = IncrCompSession :: InvalidBecauseOfErrors ;
375
+ }
376
+
377
+ pub fn incr_comp_session_dir ( & self ) -> cell:: Ref < PathBuf > {
378
+ let incr_comp_session = self . incr_comp_session . borrow ( ) ;
379
+ cell:: Ref :: map ( incr_comp_session, |incr_comp_session| {
380
+ match * incr_comp_session {
381
+ IncrCompSession :: NotInitialized |
382
+ IncrCompSession :: InvalidBecauseOfErrors => {
383
+ bug ! ( "Trying to get session directory from IncrCompSession `{:?}`" ,
384
+ * incr_comp_session)
385
+ }
386
+ IncrCompSession :: Active { ref session_directory, .. } |
387
+ IncrCompSession :: Finalized { ref session_directory } => {
388
+ session_directory
389
+ }
390
+ }
391
+ } )
392
+ }
393
+
394
+ pub fn incr_comp_session_dir_opt ( & self ) -> Option < cell:: Ref < PathBuf > > {
395
+ if self . opts . incremental . is_some ( ) {
396
+ Some ( self . incr_comp_session_dir ( ) )
397
+ } else {
398
+ None
399
+ }
400
+ }
334
401
}
335
402
336
403
pub fn build_session ( sopts : config:: Options ,
@@ -446,13 +513,37 @@ pub fn build_session_(sopts: config::Options,
446
513
injected_panic_runtime : Cell :: new ( None ) ,
447
514
available_macros : RefCell :: new ( HashSet :: new ( ) ) ,
448
515
imported_macro_spans : RefCell :: new ( HashMap :: new ( ) ) ,
516
+ incr_comp_session : RefCell :: new ( IncrCompSession :: NotInitialized ) ,
449
517
} ;
450
518
451
519
init_llvm ( & sess) ;
452
520
453
521
sess
454
522
}
455
523
524
+ /// Holds data on the current incremental compilation session, if there is one.
525
+ #[ derive( Debug ) ]
526
+ pub enum IncrCompSession {
527
+ // This is the state the session will be in until the incr. comp. dir is
528
+ // needed.
529
+ NotInitialized ,
530
+ // This is the state during which the session directory is private and can
531
+ // be modified.
532
+ Active {
533
+ session_directory : PathBuf ,
534
+ lock_file : flock:: Lock ,
535
+ } ,
536
+ // This is the state after the session directory has been finalized. In this
537
+ // state, the contents of the directory must not be modified any more.
538
+ Finalized {
539
+ session_directory : PathBuf ,
540
+ } ,
541
+ // This is an error state that is reached when some compilation error has
542
+ // occurred. It indicates that the contents of the session directory must
543
+ // not be used, since they might be invalid.
544
+ InvalidBecauseOfErrors ,
545
+ }
546
+
456
547
fn init_llvm ( sess : & Session ) {
457
548
unsafe {
458
549
// Before we touch LLVM, make sure that multithreading is enabled.
0 commit comments