about summary refs log tree commit diff
path: root/src/libsyntax/codemap.rs
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2014-09-17 19:01:33 +0300
committerEduard Burtescu <edy.burt@gmail.com>2014-09-18 14:36:18 +0300
commit07f4fda598f3fa3e7980f7d97621879fbbf00750 (patch)
treeed0c76fbf0a9428a73c73260b9035aed0323c313 /src/libsyntax/codemap.rs
parent49dd8e8c366f492d3ba3d0d2fd9d943f92073a18 (diff)
downloadrust-07f4fda598f3fa3e7980f7d97621879fbbf00750.tar.gz
rust-07f4fda598f3fa3e7980f7d97621879fbbf00750.zip
syntax: use an index in CodeMap instead of Gc for ExpnInfo.
Diffstat (limited to 'src/libsyntax/codemap.rs')
-rw-r--r--src/libsyntax/codemap.rs39
1 files changed, 30 insertions, 9 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 2f30108c27b..7fe044b0fc8 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -25,7 +25,6 @@ source code snippets, etc.
 
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 use std::cell::RefCell;
-use std::gc::Gc;
 use std::rc::Rc;
 
 pub trait Pos {
@@ -93,10 +92,10 @@ pub struct Span {
     pub hi: BytePos,
     /// Information about where the macro came from, if this piece of
     /// code was created by a macro expansion.
-    pub expn_info: Option<Gc<ExpnInfo>>
+    pub expn_id: ExpnId
 }
 
-pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None };
+pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_id: NO_EXPANSION };
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct Spanned<T> {
@@ -140,17 +139,19 @@ pub fn dummy_spanned<T>(t: T) -> Spanned<T> {
 
 /* assuming that we're not in macro expansion */
 pub fn mk_sp(lo: BytePos, hi: BytePos) -> Span {
-    Span {lo: lo, hi: hi, expn_info: None}
+    Span {lo: lo, hi: hi, expn_id: NO_EXPANSION}
 }
 
 /// Return the span itself if it doesn't come from a macro expansion,
 /// otherwise return the call site span up to the `enclosing_sp` by
 /// following the `expn_info` chain.
-pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
-    match (sp.expn_info, enclosing_sp.expn_info) {
+pub fn original_sp(cm: &CodeMap, sp: Span, enclosing_sp: Span) -> Span {
+    let call_site1 = cm.with_expn_info(sp.expn_id, |ei| ei.map(|ei| ei.call_site));
+    let call_site2 = cm.with_expn_info(enclosing_sp.expn_id, |ei| ei.map(|ei| ei.call_site));
+    match (call_site1, call_site2) {
         (None, _) => sp,
-        (Some(expn1), Some(expn2)) if expn1.call_site == expn2.call_site => sp,
-        (Some(expn1), _) => original_sp(expn1.call_site, enclosing_sp),
+        (Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp,
+        (Some(call_site1), _) => original_sp(cm, call_site1, enclosing_sp),
     }
 }
 
@@ -222,6 +223,11 @@ pub struct ExpnInfo {
     pub callee: NameAndSpan
 }
 
+#[deriving(PartialEq, Eq, Clone, Show, Hash)]
+pub struct ExpnId(u32);
+
+pub static NO_EXPANSION: ExpnId = ExpnId(-1);
+
 pub type FileName = String;
 
 pub struct FileLines {
@@ -299,13 +305,15 @@ impl FileMap {
 }
 
 pub struct CodeMap {
-    pub files: RefCell<Vec<Rc<FileMap>>>
+    pub files: RefCell<Vec<Rc<FileMap>>>,
+    expansions: RefCell<Vec<ExpnInfo>>
 }
 
 impl CodeMap {
     pub fn new() -> CodeMap {
         CodeMap {
             files: RefCell::new(Vec::new()),
+            expansions: RefCell::new(Vec::new()),
         }
     }
 
@@ -527,6 +535,19 @@ impl CodeMap {
             col: chpos - linechpos
         }
     }
+
+    pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
+        let mut expansions = self.expansions.borrow_mut();
+        expansions.push(expn_info);
+        ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1)
+    }
+
+    pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T {
+        match id {
+            NO_EXPANSION => f(None),
+            ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint]))
+        }
+    }
 }
 
 #[cfg(test)]