// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::FunctionDebugContext;
use super::metadata::file_metadata;
use super::utils::{DIB, span_start};

use llvm;
use llvm::debuginfo::{DIScope, DISubprogram};
use common::{CrateContext, FunctionContext};
use rustc::hir::pat_util;
use rustc::mir::repr::{Mir, VisibilityScope};
use rustc::util::nodemap::NodeMap;

use libc::c_uint;
use std::ptr;

use syntax_pos::{Span, Pos};
use syntax::{ast, codemap};

use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc::hir::{self, PatKind};

// This procedure builds the *scope map* for a given function, which maps any
// given ast::NodeId in the function's AST to the correct DIScope metadata instance.
//
// This builder procedure walks the AST in execution order and keeps track of
// what belongs to which scope, creating DIScope DIEs along the way, and
// introducing *artificial* lexical scope descriptors where necessary. These
// artificial scopes allow GDB to correctly handle name shadowing.
pub fn create_scope_map(cx: &CrateContext,
                        args: &[hir::Arg],
                        fn_entry_block: &hir::Block,
                        fn_metadata: DISubprogram,
                        fn_ast_id: ast::NodeId)
                        -> NodeMap<DIScope> {
    let mut scope_map = NodeMap();
    let mut scope_stack = vec!(ScopeStackEntry { scope_metadata: fn_metadata, name: None });
    scope_map.insert(fn_ast_id, fn_metadata);

    // Push argument identifiers onto the stack so arguments integrate nicely
    // with variable shadowing.
    for arg in args {
        pat_util::pat_bindings(&arg.pat, |_, node_id, _, path1| {
            scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
                                               name: Some(path1.node) });
            scope_map.insert(node_id, fn_metadata);
        })
    }

    // Clang creates a separate scope for function bodies, so let's do this too.
    with_new_scope(cx,
                   fn_entry_block.span,
                   &mut scope_stack,
                   &mut scope_map,
                   |cx, scope_stack, scope_map| {
        walk_block(cx, fn_entry_block, scope_stack, scope_map);
    });

    return scope_map;
}

/// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
/// If debuginfo is disabled, the returned vector is empty.
pub fn create_mir_scopes(fcx: &FunctionContext) -> IndexVec<VisibilityScope, DIScope> {
    let mir = fcx.mir.clone().expect("create_mir_scopes: missing MIR for fn");
    let mut scopes = IndexVec::from_elem(ptr::null_mut(), &mir.visibility_scopes);

    let fn_metadata = match fcx.debug_context {
        FunctionDebugContext::RegularContext(box ref data) => data.fn_metadata,
        FunctionDebugContext::DebugInfoDisabled |
        FunctionDebugContext::FunctionWithoutDebugInfo => {
            return scopes;
        }
    };

    // Find all the scopes with variables defined in them.
    let mut has_variables = BitVector::new(mir.visibility_scopes.len());
    for var in &mir.var_decls {
        has_variables.insert(var.source_info.scope.index());
    }

    // Instantiate all scopes.
    for idx in 0..mir.visibility_scopes.len() {
        let scope = VisibilityScope::new(idx);
        make_mir_scope(fcx.ccx, &mir, &has_variables, fn_metadata, scope, &mut scopes);
    }

    scopes
}

fn make_mir_scope(ccx: &CrateContext,
                  mir: &Mir,
                  has_variables: &BitVector,
                  fn_metadata: DISubprogram,
                  scope: VisibilityScope,
                  scopes: &mut IndexVec<VisibilityScope, DIScope>) {
    if !scopes[scope].is_null() {
        return;
    }

    let scope_data = &mir.visibility_scopes[scope];
    let parent_scope = if let Some(parent) = scope_data.parent_scope {
        make_mir_scope(ccx, mir, has_variables, fn_metadata, parent, scopes);
        scopes[parent]
    } else {
        // The root is the function itself.
        scopes[scope] = fn_metadata;
        return;
    };

    if !has_variables.contains(scope.index()) {
        // Do not create a DIScope if there are no variables
        // defined in this MIR Scope, to avoid debuginfo bloat.

        // However, we don't skip creating a nested scope if
        // our parent is the root, because we might want to
        // put arguments in the root and not have shadowing.
        if parent_scope != fn_metadata {
            scopes[scope] = parent_scope;
            return;
        }
    }

    let loc = span_start(ccx, scope_data.span);
    scopes[scope] = unsafe {
    let file_metadata = file_metadata(ccx, &loc.file.name, &loc.file.abs_path);
        llvm::LLVMDIBuilderCreateLexicalBlock(
            DIB(ccx),
            parent_scope,
            file_metadata,
            loc.line as c_uint,
            loc.col.to_usize() as c_uint)
    };
}

// local helper functions for walking the AST.
fn with_new_scope<F>(cx: &CrateContext,
                     scope_span: Span,
                     scope_stack: &mut Vec<ScopeStackEntry> ,
                     scope_map: &mut NodeMap<DIScope>,
                     inner_walk: F) where
    F: FnOnce(&CrateContext, &mut Vec<ScopeStackEntry>, &mut NodeMap<DIScope>),
{
    // Create a new lexical scope and push it onto the stack
    let loc = span_start(cx, scope_span);
    let file_metadata = file_metadata(cx, &loc.file.name, &loc.file.abs_path);
    let parent_scope = scope_stack.last().unwrap().scope_metadata;

    let scope_metadata = unsafe {
        llvm::LLVMDIBuilderCreateLexicalBlock(
            DIB(cx),
            parent_scope,
            file_metadata,
            loc.line as c_uint,
            loc.col.to_usize() as c_uint)
    };

    scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata, name: None });

    inner_walk(cx, scope_stack, scope_map);

    // pop artificial scopes
    while scope_stack.last().unwrap().name.is_some() {
        scope_stack.pop();
    }

    if scope_stack.last().unwrap().scope_metadata != scope_metadata {
        span_bug!(scope_span, "debuginfo: Inconsistency in scope management.");
    }

    scope_stack.pop();
}

struct ScopeStackEntry {
    scope_metadata: DIScope,
    name: Option<ast::Name>
}

fn walk_block(cx: &CrateContext,
              block: &hir::Block,
              scope_stack: &mut Vec<ScopeStackEntry> ,
              scope_map: &mut NodeMap<DIScope>) {
    scope_map.insert(block.id, scope_stack.last().unwrap().scope_metadata);

    // The interesting things here are statements and the concluding expression.
    for statement in &block.stmts {
        scope_map.insert(statement.node.id(),
                         scope_stack.last().unwrap().scope_metadata);

        match statement.node {
            hir::StmtDecl(ref decl, _) =>
                walk_decl(cx, &decl, scope_stack, scope_map),
            hir::StmtExpr(ref exp, _) |
            hir::StmtSemi(ref exp, _) =>
                walk_expr(cx, &exp, scope_stack, scope_map),
        }
    }

    if let Some(ref exp) = block.expr {
        walk_expr(cx, &exp, scope_stack, scope_map);
    }
}

fn walk_decl(cx: &CrateContext,
             decl: &hir::Decl,
             scope_stack: &mut Vec<ScopeStackEntry> ,
             scope_map: &mut NodeMap<DIScope>) {
    match *decl {
        codemap::Spanned { node: hir::DeclLocal(ref local), .. } => {
            scope_map.insert(local.id, scope_stack.last().unwrap().scope_metadata);

            walk_pattern(cx, &local.pat, scope_stack, scope_map);

            if let Some(ref exp) = local.init {
                walk_expr(cx, &exp, scope_stack, scope_map);
            }
        }
        _ => ()
    }
}

fn walk_pattern(cx: &CrateContext,
                pat: &hir::Pat,
                scope_stack: &mut Vec<ScopeStackEntry> ,
                scope_map: &mut NodeMap<DIScope>) {
    // Unfortunately, we cannot just use pat_util::pat_bindings() or
    // ast_util::walk_pat() here because we have to visit *all* nodes in
    // order to put them into the scope map. The above functions don't do that.
    match pat.node {
        PatKind::Binding(_, ref path1, ref sub_pat_opt) => {
            // LLVM does not properly generate 'DW_AT_start_scope' fields
            // for variable DIEs. For this reason we have to introduce
            // an artificial scope at bindings whenever a variable with
            // the same name is declared in *any* parent scope.
            //
            // Otherwise the following error occurs:
            //
            // let x = 10;
            //
            // do_something(); // 'gdb print x' correctly prints 10
            //
            // {
            //     do_something(); // 'gdb print x' prints 0, because it
            //                     // already reads the uninitialized 'x'
            //                     // from the next line...
            //     let x = 100;
            //     do_something(); // 'gdb print x' correctly prints 100
            // }

            // Is there already a binding with that name?
            // N.B.: this comparison must be UNhygienic... because
            // gdb knows nothing about the context, so any two
            // variables with the same name will cause the problem.
            let name = path1.node;
            let need_new_scope = scope_stack
                .iter()
                .any(|entry| entry.name == Some(name));

            if need_new_scope {
                // Create a new lexical scope and push it onto the stack
                let loc = span_start(cx, pat.span);
                let file_metadata = file_metadata(cx, &loc.file.name, &loc.file.abs_path);
                let parent_scope = scope_stack.last().unwrap().scope_metadata;

                let scope_metadata = unsafe {
                    llvm::LLVMDIBuilderCreateLexicalBlock(
                        DIB(cx),
                        parent_scope,
                        file_metadata,
                        loc.line as c_uint,
                        loc.col.to_usize() as c_uint)
                };

                scope_stack.push(ScopeStackEntry {
                    scope_metadata: scope_metadata,
                    name: Some(name)
                });

            } else {
                // Push a new entry anyway so the name can be found
                let prev_metadata = scope_stack.last().unwrap().scope_metadata;
                scope_stack.push(ScopeStackEntry {
                    scope_metadata: prev_metadata,
                    name: Some(name)
                });
            }

            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);

            if let Some(ref sub_pat) = *sub_pat_opt {
                walk_pattern(cx, &sub_pat, scope_stack, scope_map);
            }
        }

        PatKind::Wild => {
            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
        }

        PatKind::TupleStruct(_, ref sub_pats, _) => {
            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);

            for p in sub_pats {
                walk_pattern(cx, &p, scope_stack, scope_map);
            }
        }

        PatKind::Path(..) => {
            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
        }

        PatKind::Struct(_, ref field_pats, _) => {
            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);

            for &codemap::Spanned {
                node: hir::FieldPat { pat: ref sub_pat, .. },
                ..
            } in field_pats {
                walk_pattern(cx, &sub_pat, scope_stack, scope_map);
            }
        }

        PatKind::Tuple(ref sub_pats, _) => {
            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);

            for sub_pat in sub_pats {
                walk_pattern(cx, &sub_pat, scope_stack, scope_map);
            }
        }

        PatKind::Box(ref sub_pat) | PatKind::Ref(ref sub_pat, _) => {
            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
            walk_pattern(cx, &sub_pat, scope_stack, scope_map);
        }

        PatKind::Lit(ref exp) => {
            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
            walk_expr(cx, &exp, scope_stack, scope_map);
        }

        PatKind::Range(ref exp1, ref exp2) => {
            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
            walk_expr(cx, &exp1, scope_stack, scope_map);
            walk_expr(cx, &exp2, scope_stack, scope_map);
        }

        PatKind::Vec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
            scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);

            for sub_pat in front_sub_pats {
                walk_pattern(cx, &sub_pat, scope_stack, scope_map);
            }

            if let Some(ref sub_pat) = *middle_sub_pats {
                walk_pattern(cx, &sub_pat, scope_stack, scope_map);
            }

            for sub_pat in back_sub_pats {
                walk_pattern(cx, &sub_pat, scope_stack, scope_map);
            }
        }
    }
}

fn walk_expr(cx: &CrateContext,
             exp: &hir::Expr,
             scope_stack: &mut Vec<ScopeStackEntry> ,
             scope_map: &mut NodeMap<DIScope>) {

    scope_map.insert(exp.id, scope_stack.last().unwrap().scope_metadata);

    match exp.node {
        hir::ExprLit(_)   |
        hir::ExprBreak(_) |
        hir::ExprAgain(_) |
        hir::ExprPath(..) => {}

        hir::ExprCast(ref sub_exp, _)     |
        hir::ExprType(ref sub_exp, _) |
        hir::ExprAddrOf(_, ref sub_exp)  |
        hir::ExprField(ref sub_exp, _) |
        hir::ExprTupField(ref sub_exp, _) =>
            walk_expr(cx, &sub_exp, scope_stack, scope_map),

        hir::ExprBox(ref sub_expr) => {
            walk_expr(cx, &sub_expr, scope_stack, scope_map);
        }

        hir::ExprRet(ref exp_opt) => match *exp_opt {
            Some(ref sub_exp) => walk_expr(cx, &sub_exp, scope_stack, scope_map),
            None => ()
        },

        hir::ExprUnary(_, ref sub_exp) => {
            walk_expr(cx, &sub_exp, scope_stack, scope_map);
        }

        hir::ExprAssignOp(_, ref lhs, ref rhs) |
        hir::ExprIndex(ref lhs, ref rhs) |
        hir::ExprBinary(_, ref lhs, ref rhs)    => {
            walk_expr(cx, &lhs, scope_stack, scope_map);
            walk_expr(cx, &rhs, scope_stack, scope_map);
        }

        hir::ExprVec(ref init_expressions) |
        hir::ExprTup(ref init_expressions) => {
            for ie in init_expressions {
                walk_expr(cx, &ie, scope_stack, scope_map);
            }
        }

        hir::ExprAssign(ref sub_exp1, ref sub_exp2) |
        hir::ExprRepeat(ref sub_exp1, ref sub_exp2) => {
            walk_expr(cx, &sub_exp1, scope_stack, scope_map);
            walk_expr(cx, &sub_exp2, scope_stack, scope_map);
        }

        hir::ExprIf(ref cond_exp, ref then_block, ref opt_else_exp) => {
            walk_expr(cx, &cond_exp, scope_stack, scope_map);

            with_new_scope(cx,
                           then_block.span,
                           scope_stack,
                           scope_map,
                           |cx, scope_stack, scope_map| {
                walk_block(cx, &then_block, scope_stack, scope_map);
            });

            match *opt_else_exp {
                Some(ref else_exp) =>
                    walk_expr(cx, &else_exp, scope_stack, scope_map),
                _ => ()
            }
        }

        hir::ExprWhile(ref cond_exp, ref loop_body, _) => {
            walk_expr(cx, &cond_exp, scope_stack, scope_map);

            with_new_scope(cx,
                           loop_body.span,
                           scope_stack,
                           scope_map,
                           |cx, scope_stack, scope_map| {
                walk_block(cx, &loop_body, scope_stack, scope_map);
            })
        }

        hir::ExprLoop(ref block, _) |
        hir::ExprBlock(ref block)   => {
            with_new_scope(cx,
                           block.span,
                           scope_stack,
                           scope_map,
                           |cx, scope_stack, scope_map| {
                walk_block(cx, &block, scope_stack, scope_map);
            })
        }

        hir::ExprClosure(_, ref decl, ref block, _) => {
            with_new_scope(cx,
                           block.span,
                           scope_stack,
                           scope_map,
                           |cx, scope_stack, scope_map| {
                for &hir::Arg { pat: ref pattern, .. } in &decl.inputs {
                    walk_pattern(cx, &pattern, scope_stack, scope_map);
                }

                walk_block(cx, &block, scope_stack, scope_map);
            })
        }

        hir::ExprCall(ref fn_exp, ref args) => {
            walk_expr(cx, &fn_exp, scope_stack, scope_map);

            for arg_exp in args {
                walk_expr(cx, &arg_exp, scope_stack, scope_map);
            }
        }

        hir::ExprMethodCall(_, _, ref args) => {
            for arg_exp in args {
                walk_expr(cx, &arg_exp, scope_stack, scope_map);
            }
        }

        hir::ExprMatch(ref discriminant_exp, ref arms, _) => {
            walk_expr(cx, &discriminant_exp, scope_stack, scope_map);

            // For each arm we have to first walk the pattern as these might
            // introduce new artificial scopes. It should be sufficient to
            // walk only one pattern per arm, as they all must contain the
            // same binding names.

            for arm_ref in arms {
                let arm_span = arm_ref.pats[0].span;

                with_new_scope(cx,
                               arm_span,
                               scope_stack,
                               scope_map,
                               |cx, scope_stack, scope_map| {
                    for pat in &arm_ref.pats {
                        walk_pattern(cx, &pat, scope_stack, scope_map);
                    }

                    if let Some(ref guard_exp) = arm_ref.guard {
                        walk_expr(cx, &guard_exp, scope_stack, scope_map)
                    }

                    walk_expr(cx, &arm_ref.body, scope_stack, scope_map);
                })
            }
        }

        hir::ExprStruct(_, ref fields, ref base_exp) => {
            for &hir::Field { expr: ref exp, .. } in fields {
                walk_expr(cx, &exp, scope_stack, scope_map);
            }

            match *base_exp {
                Some(ref exp) => walk_expr(cx, &exp, scope_stack, scope_map),
                None => ()
            }
        }

        hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
            for output in outputs {
                walk_expr(cx, output, scope_stack, scope_map);
            }

            for input in inputs {
                walk_expr(cx, input, scope_stack, scope_map);
            }
        }
    }
}
