@@ -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,76 @@ 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
+ let session_directory = match * incr_comp_session {
370
+ IncrCompSession :: Active { ref session_directory, .. } => {
371
+ session_directory. clone ( )
372
+ }
373
+ _ => bug ! ( "Trying to invalidate IncrCompSession `{:?}`" ,
374
+ * incr_comp_session) ,
375
+ } ;
376
+
377
+ // Note: This will also drop the lock file, thus unlocking the directory
378
+ * incr_comp_session = IncrCompSession :: InvalidBecauseOfErrors {
379
+ session_directory : session_directory
380
+ } ;
381
+ }
382
+
383
+ pub fn incr_comp_session_dir ( & self ) -> cell:: Ref < PathBuf > {
384
+ let incr_comp_session = self . incr_comp_session . borrow ( ) ;
385
+ cell:: Ref :: map ( incr_comp_session, |incr_comp_session| {
386
+ match * incr_comp_session {
387
+ IncrCompSession :: NotInitialized => {
388
+ bug ! ( "Trying to get session directory from IncrCompSession `{:?}`" ,
389
+ * incr_comp_session)
390
+ }
391
+ IncrCompSession :: Active { ref session_directory, .. } |
392
+ IncrCompSession :: Finalized { ref session_directory } |
393
+ IncrCompSession :: InvalidBecauseOfErrors { ref session_directory } => {
394
+ session_directory
395
+ }
396
+ }
397
+ } )
398
+ }
399
+
400
+ pub fn incr_comp_session_dir_opt ( & self ) -> Option < cell:: Ref < PathBuf > > {
401
+ if self . opts . incremental . is_some ( ) {
402
+ Some ( self . incr_comp_session_dir ( ) )
403
+ } else {
404
+ None
405
+ }
406
+ }
334
407
}
335
408
336
409
pub fn build_session ( sopts : config:: Options ,
@@ -446,13 +519,39 @@ pub fn build_session_(sopts: config::Options,
446
519
injected_panic_runtime : Cell :: new ( None ) ,
447
520
available_macros : RefCell :: new ( HashSet :: new ( ) ) ,
448
521
imported_macro_spans : RefCell :: new ( HashMap :: new ( ) ) ,
522
+ incr_comp_session : RefCell :: new ( IncrCompSession :: NotInitialized ) ,
449
523
} ;
450
524
451
525
init_llvm ( & sess) ;
452
526
453
527
sess
454
528
}
455
529
530
+ /// Holds data on the current incremental compilation session, if there is one.
531
+ #[ derive( Debug ) ]
532
+ pub enum IncrCompSession {
533
+ // This is the state the session will be in until the incr. comp. dir is
534
+ // needed.
535
+ NotInitialized ,
536
+ // This is the state during which the session directory is private and can
537
+ // be modified.
538
+ Active {
539
+ session_directory : PathBuf ,
540
+ lock_file : flock:: Lock ,
541
+ } ,
542
+ // This is the state after the session directory has been finalized. In this
543
+ // state, the contents of the directory must not be modified any more.
544
+ Finalized {
545
+ session_directory : PathBuf ,
546
+ } ,
547
+ // This is an error state that is reached when some compilation error has
548
+ // occurred. It indicates that the contents of the session directory must
549
+ // not be used, since they might be invalid.
550
+ InvalidBecauseOfErrors {
551
+ session_directory : PathBuf ,
552
+ }
553
+ }
554
+
456
555
fn init_llvm ( sess : & Session ) {
457
556
unsafe {
458
557
// Before we touch LLVM, make sure that multithreading is enabled.
0 commit comments