Skip to content

Commit

Permalink
Changed macro spans in CSVs to point to the macro name, bugfixed nest…
Browse files Browse the repository at this point in the history
…ed spans
  • Loading branch information
DanielJCampbell committed Feb 3, 2016
1 parent 50df6b9 commit b361b7f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 8 deletions.
14 changes: 9 additions & 5 deletions src/librustc_trans/save/dump_csv.rs
Expand Up @@ -847,13 +847,17 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
if !self.mac_defs.contains(&data.callee_span)
&& !data.imported {
self.mac_defs.insert(data.callee_span);
self.fmt.macro_str(data.callee_span, data.callee_span,
data.name.clone(), qualname.clone());
if let Some(sub_span) = self.span.span_for_macro_def_name(data.callee_span) {
self.fmt.macro_str(data.callee_span, sub_span,
data.name.clone(), qualname.clone());
}
}
if !self.mac_uses.contains(&data.span) {
self.mac_uses.insert(data.span);
self.fmt.macro_use_str(data.span, data.span, data.name,
qualname, data.scope);
self.mac_uses.insert(data.span);
if let Some(sub_span) = self.span.span_for_macro_use_name(data.span) {
self.fmt.macro_use_str(data.span, sub_span, data.name,
qualname, data.scope);
}
}
}
}
Expand Down
24 changes: 22 additions & 2 deletions src/librustc_trans/save/span_utils.rs
Expand Up @@ -378,8 +378,8 @@ impl<'a> SpanUtils<'a> {
}
}

// Given a macro_rules definition span, return the span of the macro's name.
pub fn span_for_macro_name(&self, span: Span) -> Option<Span> {
// Return the name for a macro definition (identifier after first `!`)
pub fn span_for_macro_def_name(&self, span: Span) -> Option<Span> {
let mut toks = self.retokenise_span(span);
loop {
let ts = toks.real_token();
Expand All @@ -397,6 +397,26 @@ impl<'a> SpanUtils<'a> {
}
}

// Return the name for a macro use (identifier before first `!`).
pub fn span_for_macro_use_name(&self, span:Span) -> Option<Span> {
let mut toks = self.retokenise_span(span);
let mut prev = toks.real_token();
loop {
if prev.tok == token::Eof {
return None;
}
let ts = toks.real_token();
if ts.tok == token::Not {
if prev.tok.is_ident() {
return self.make_sub_span(span, Some(prev.sp));
} else {
return None;
}
}
prev = ts;
}
}

/// Return true if the span is generated code, and
/// it is not a subspan of the root callsite.
///
Expand Down
21 changes: 20 additions & 1 deletion src/libsyntax/codemap.rs
Expand Up @@ -1052,9 +1052,18 @@ impl CodeMap {
/// the macro callsite that expanded to it.
pub fn source_callsite(&self, sp: Span) -> Span {
let mut span = sp;
// Special case - if a macro is parsed as an argument to another macro, the source
// callsite is the first callsite, which is also source-equivalent to the span.
let mut first = true;
while span.expn_id != NO_EXPANSION && span.expn_id != COMMAND_LINE_EXPN {
if let Some(callsite) = self.with_expn_info(span.expn_id,
|ei| ei.map(|ei| ei.call_site.clone())) {
if first && span.source_equal(&callsite) {
if self.lookup_char_pos(span.lo).file.is_real_file() {
return Span { expn_id: NO_EXPANSION, .. span };
}
}
first = false;
span = callsite;
}
else {
Expand All @@ -1071,10 +1080,20 @@ impl CodeMap {
/// corresponding to the source callsite.
pub fn source_callee(&self, sp: Span) -> Option<NameAndSpan> {
let mut span = sp;
// Special case - if a macro is parsed as an argument to another macro, the source
// callsite is source-equivalent to the span, and the source callee is the first callee.
let mut first = true;
while let Some(callsite) = self.with_expn_info(span.expn_id,
|ei| ei.map(|ei| ei.call_site.clone())) {
if first && span.source_equal(&callsite) {
if self.lookup_char_pos(span.lo).file.is_real_file() {
return self.with_expn_info(span.expn_id,
|ei| ei.map(|ei| ei.callee.clone()));
}
}
first = false;
if let Some(_) = self.with_expn_info(callsite.expn_id,
|ei| ei.map(|ei| ei.call_site.clone())) {
|ei| ei.map(|ei| ei.call_site.clone())) {
span = callsite;
}
else {
Expand Down

0 comments on commit b361b7f

Please sign in to comment.