Skip to content

Commit

Permalink
keep track of filenames in IR with metadata push/pop
Browse files Browse the repository at this point in the history
- add location info to empty blocks; fixes #15280
- remove file names from non-initial `line` nodes
- emit `(meta push_loc filename)` and `(meta pop_loc)` around nested
  blocks from different files, to handle macros
- fix line number of `catch` blocks
  • Loading branch information
JeffBezanson committed Mar 29, 2016
1 parent 96fb049 commit 45111a8
Show file tree
Hide file tree
Showing 17 changed files with 138 additions and 121 deletions.
3 changes: 1 addition & 2 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@
#end

#immutable LineNumberNode
# file::Symbol
# line::Int
#end

Expand Down Expand Up @@ -280,7 +279,7 @@ _new(:TopNode, :Symbol)
_new(:NewvarNode, :Slot)
_new(:QuoteNode, :ANY)
_new(:GenSym, :Int)
eval(:((::Type{LineNumberNode})(f::Symbol, l::Int) = $(Expr(:new, :LineNumberNode, :f, :l))))
eval(:((::Type{LineNumberNode})(l::Int) = $(Expr(:new, :LineNumberNode, :l))))
eval(:((::Type{GlobalRef})(m::Module, s::Symbol) = $(Expr(:new, :GlobalRef, :m, :s))))
eval(:((::Type{Slot})(n::Int) = $(Expr(:new, :Slot, :n, Any))))
eval(:((::Type{Slot})(n::Int, t::ANY) = $(Expr(:new, :Slot, :n, :t))))
Expand Down
4 changes: 2 additions & 2 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ end
## AST printing ##

show_unquoted(io::IO, sym::Symbol, ::Int, ::Int) = print(io, sym)
show_unquoted(io::IO, ex::LineNumberNode, ::Int, ::Int) = show_linenumber(io, ex.line, ex.file)
show_unquoted(io::IO, ex::LineNumberNode, ::Int, ::Int) = show_linenumber(io, ex.line)
show_unquoted(io::IO, ex::LabelNode, ::Int, ::Int) = print(io, ex.label, ": ")
show_unquoted(io::IO, ex::GotoNode, ::Int, ::Int) = print(io, "goto ", ex.label)
show_unquoted(io::IO, ex::TopNode, ::Int, ::Int) = print(io,"top(",ex.name,')')
Expand Down Expand Up @@ -539,7 +539,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int)
head, args, nargs = ex.head, ex.args, length(ex.args)
emphstate = typeemphasize(io)
show_type = true
if (ex.head == :(=) ||
if (ex.head == :(=) || ex.head == :line ||
ex.head == :boundscheck ||
ex.head == :gotoifnot ||
ex.head == :return)
Expand Down
3 changes: 1 addition & 2 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,11 @@ JL_DLLEXPORT void jl_lambda_info_set_ast(jl_lambda_info_t *li, jl_value_t *ast)
li->pure = 1;
jl_value_t *body1 = skip_meta(body);
if (jl_is_linenode(body1)) {
li->file = jl_linenode_file(body1);
li->line = jl_linenode_line(body1);
}
else if (jl_is_expr(body1) && ((jl_expr_t*)body1)->head == line_sym) {
li->file = (jl_sym_t*)jl_exprarg(body1, 1);
li->line = jl_unbox_long(jl_exprarg(body1, 0));
li->file = (jl_sym_t*)jl_exprarg(body1, 1);
}
jl_array_t *vis = jl_lam_vinfo((jl_expr_t*)ast);
jl_array_t *args = jl_lam_args((jl_expr_t*)ast);
Expand Down
26 changes: 6 additions & 20 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,16 +496,10 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, int eo)
else
n++;
if (!eo) {
if (sym == line_sym && n==2) {
// NOTE: n==3 case exists: '(line, linenum, filename, funcname) passes
// the original name through to keyword-arg specializations.
// See 'line handling in julia-syntax.scm:keywords-method-def-expr
jl_value_t *filename = NULL, *linenum = NULL;
JL_GC_PUSH2(&filename, &linenum);
filename = scm_to_julia_(fl_ctx, car_(cdr_(e)), 0);
linenum = scm_to_julia_(fl_ctx, car_(e), 0);
jl_value_t *temp = jl_new_struct(jl_linenumbernode_type,
filename, linenum);
if (sym == line_sym && n==1) {
jl_value_t *linenum = scm_to_julia_(fl_ctx, car_(e), 0);
JL_GC_PUSH1(&linenum);
jl_value_t *temp = jl_new_struct(jl_linenumbernode_type, linenum);
JL_GC_POP();
return temp;
}
Expand Down Expand Up @@ -659,21 +653,13 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v)
fl_free_gc_handles(fl_ctx, 1);
return scmv;
}
if (jl_typeis(v, jl_linenumbernode_type)) {
// GC Note: jl_fieldref(v, 1) allocates but neither jl_fieldref(v, 0)
// or julia_to_list2 should allocate here
value_t args = julia_to_list2(fl_ctx, jl_fieldref(v,1), jl_fieldref(v,0));
fl_gc_handle(fl_ctx, &args);
value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)line_sym);
value_t scmv = fl_cons(fl_ctx, hd, args);
fl_free_gc_handles(fl_ctx, 1);
return scmv;
}
// GC Note: jl_fieldref(v, 0) allocate for LabelNode, GotoNode
// but we don't need a GC root here because julia_to_list2
// shouldn't allocate in this case.
if (jl_typeis(v, jl_slot_type))
return julia_to_list2(fl_ctx, (jl_value_t*)slot_sym, jl_fieldref(v,0));
if (jl_typeis(v, jl_linenumbernode_type))
return julia_to_list2(fl_ctx, (jl_value_t*)line_sym, jl_fieldref(v,0));
if (jl_typeis(v, jl_labelnode_type))
return julia_to_list2(fl_ctx, (jl_value_t*)label_sym, jl_fieldref(v,0));
if (jl_typeis(v, jl_gotonode_type))
Expand Down
3 changes: 1 addition & 2 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -1379,8 +1379,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v,
n += jl_printf(out, ")");
}
else if (vt == jl_linenumbernode_type) {
n += jl_printf(out, "# line %" PRIuPTR " %s",
jl_linenode_line(v), jl_symbol_name(jl_linenode_file(v)));
n += jl_printf(out, "# line %" PRIuPTR, jl_linenode_line(v));
}
else if (vt == jl_expr_type) {
jl_expr_t *e = (jl_expr_t*)v;
Expand Down
2 changes: 2 additions & 0 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ JL_DLLEXPORT Type *julia_type_to_llvm(jl_value_t *jt, bool *isboxed)
return PointerType::get(lt, 0);
}
if (jl_is_bitstype(jt)) {
if (jt == (jl_value_t*)jl_long_type)
return T_size;
int nb = jl_datatype_size(jt);
if (jl_is_floattype(jt)) {
#ifndef DISABLE_FLOAT16
Expand Down
9 changes: 3 additions & 6 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4129,13 +4129,12 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
bool do_coverage = jl_options.code_coverage == JL_LOG_ALL || (jl_options.code_coverage == JL_LOG_USER && in_user_code);
bool do_malloc_log = jl_options.malloc_log == JL_LOG_ALL || (jl_options.malloc_log == JL_LOG_USER && in_user_code);
jl_value_t *stmt = skip_meta(stmts);
StringRef filename = "<no file>";
StringRef filename = jl_symbol_name(lam->file);
StringRef dbgFuncName = jl_symbol_name(lam->name);
int lno = -1;
// look for initial (line num filename [funcname]) node, [funcname] for kwarg methods.
if (jl_is_linenode(stmt)) {
lno = jl_linenode_line(stmt);
filename = jl_symbol_name(jl_linenode_file(stmt));
}
else if (jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == line_sym &&
jl_array_dim0(((jl_expr_t*)stmt)->args) > 0) {
Expand Down Expand Up @@ -4626,10 +4625,9 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
if (jl_is_linenode(stmt) ||
(jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == line_sym)) {

jl_sym_t *file = NULL;
jl_sym_t *file=NULL;
if (jl_is_linenode(stmt)) {
lno = jl_linenode_line(stmt);
file = jl_linenode_file(stmt);
}
else if (jl_is_expr(stmt)) {
lno = jl_unbox_long(jl_exprarg(stmt,0));
Expand All @@ -4640,7 +4638,6 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
}
}
}
assert(jl_symbol_name(file));

# ifdef LLVM37
DIFile *dfil = NULL;
Expand All @@ -4649,7 +4646,7 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
# endif

// If the string is not empty
if (*jl_symbol_name(file) != '\0') {
if (file && *jl_symbol_name(file) != '\0') {
# ifdef LLVM37
std::map<jl_sym_t *, DIFile *>::iterator it = filescopes.find(file);
# else
Expand Down
3 changes: 2 additions & 1 deletion src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ JL_DLLEXPORT jl_lambda_info_t *jl_instantiate_staged(jl_lambda_info_t *generator
jl_cellset(((jl_expr_t*)jl_exprarg(ex,1))->args, 0, body);

linenum = jl_box_long(generator->line);
jl_value_t *linenode = jl_new_struct(jl_linenumbernode_type, generator->file, linenum);
jl_value_t *linenode = jl_new_struct(jl_linenumbernode_type, linenum);
jl_cellset(body->args, 0, linenode);

// invoke code generator
Expand All @@ -939,6 +939,7 @@ JL_DLLEXPORT jl_lambda_info_t *jl_instantiate_staged(jl_lambda_info_t *generator
func->name = generator->name;
if (generator->isva)
func->isva = 1;
func->file = generator->file;
JL_GC_POP();
return func;
}
Expand Down
4 changes: 2 additions & 2 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -3449,8 +3449,8 @@ void jl_init_types(void)

jl_linenumbernode_type =
jl_new_datatype(jl_symbol("LineNumberNode"), jl_any_type, jl_emptysvec,
jl_svec(2, jl_symbol("file"), jl_symbol("line")),
jl_svec(2, jl_symbol_type, jl_long_type), 0, 0, 2);
jl_svec(1, jl_symbol("line")),
jl_svec(1, jl_long_type), 0, 0, 1);

jl_labelnode_type =
jl_new_datatype(jl_symbol("LabelNode"), jl_any_type, jl_emptysvec,
Expand Down
41 changes: 15 additions & 26 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,9 @@
(if (invalid-initial-token? t)
(error (string "unexpected \"" t "\"")))
(if (closer? t)
(list head) ; empty block
(if add-linenums ;; empty block
(list head (line-number-node s))
(list head))
(let loop ((ex
;; in allow-empty mode skip leading runs of operator
(if (and allow-empty (memv t ops))
Expand Down Expand Up @@ -1133,7 +1135,10 @@
(error "let variables should end in \";\" or newline"))
(let ((ex (parse-block s)))
(expect-end s word)
`(let ,ex ,@binds))))
;; don't need line info in an empty let block
(if (and (length= ex 2) (pair? (cadr ex)) (eq? (caadr ex) 'line))
`(let (block) ,@binds)
`(let ,ex ,@binds)))))
((global local)
(let* ((lno (input-port-line (ts:port s)))
(const (and (eq? (peek-token s) 'const)
Expand Down Expand Up @@ -1165,24 +1170,18 @@
(eq? (car sig) 'tuple))))
(error (string "expected \"(\" in " word " definition"))
sig)))
(loc (begin (if (not (eq? (peek-token s) 'end))
;; if ends on same line, don't skip the following newline
(skip-ws-and-comments (ts:port s)))
(line-number-node s)))
(body (parse-block s)))
(expect-end s word)
(add-filename-to-block! body loc)
(list word def body)))))
((abstract)
(list 'abstract (parse-subtype-spec s)))
((type immutable)
(let ((immu? (eq? word 'immutable)))
(if (reserved-word? (peek-token s))
(error (string "invalid type name \"" (take-token s) "\"")))
(let ((sig (parse-subtype-spec s))
(loc (line-number-node s)))
(let ((sig (parse-subtype-spec s)))
(begin0 (list 'type (if (eq? word 'type) #t #f)
sig (add-filename-to-block! (parse-block s) loc))
sig (parse-block s))
(expect-end s word)))))
((bitstype)
(list 'bitstype (with-space-sensitive (parse-cond s))
Expand Down Expand Up @@ -1218,15 +1217,13 @@
'(block)
#f
finalb)
(let* ((var (if nl (parse-eq s) (parse-eq* s)))
(let* ((var (if nl #f (parse-eq* s)))
(var? (and (not nl) (or (symbol? var) (and (length= var 2) (eq? (car var) '$)))))
(catch-block (if (eq? (require-token s) 'finally)
'(block)
(parse-block s))))
(loop (require-token s)
(if var?
catch-block
`(block ,var ,@(cdr catch-block)))
catch-block
(and var? var)
finalb)))))
((and (eq? nxt 'finally)
Expand Down Expand Up @@ -1305,23 +1302,15 @@
(error "invalid \"do\" syntax"))
(else (error "unhandled reserved word")))))))

(define (add-filename-to-block! body loc)
(if (and (length> body 1)
(pair? (cadr body))
(eq? (caadr body) 'line))
(set-car! (cdr body) loc))
body)

(define (parse-do s)
(with-bindings
((expect-end-current-line (input-port-line (ts:port s))))
(without-whitespace-newline
(let* ((doargs (if (memv (peek-token s) '(#\newline #\;))
'()
(parse-comma-separated s parse-range)))
(loc (line-number-node s)))
(let ((doargs (if (memv (peek-token s) '(#\newline #\;))
'()
(parse-comma-separated s parse-range))))
`(-> (tuple ,@doargs)
,(begin0 (add-filename-to-block! (parse-block s) loc)
,(begin0 (parse-block s)
(expect-end s 'do)))))))

(define (macrocall-to-atsym e)
Expand Down
Loading

0 comments on commit 45111a8

Please sign in to comment.