#   Copyright 2013 Free Software Foundation, Inc.
#
#   This is free software: you can redistribute it and/or modify it
#   under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful, but
#   WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see
#   <http://www.gnu.org/licenses/>.

import gcc
import gccutils
import sys

want_raii_info = False

logging = False
show_cfg = False

def log(msg, indent=0):
    global logging
    if logging:
        sys.stderr.write('%s%s\n' % ('  ' * indent, msg))
        sys.stderr.flush()

def is_cleanup_type(return_type):
    if not isinstance(return_type, gcc.PointerType):
        return False
    if not isinstance(return_type.dereference, gcc.RecordType):
        return False
    if str(return_type.dereference.name) == 'cleanup':
        return True
    return False

def is_constructor(decl):
    "Return True if the function DECL is a cleanup constructor; False otherwise"
    return is_cleanup_type(decl.type.type) and (not decl.name or str(decl.name) != 'make_final_cleanup')

destructor_names = set(['do_cleanups', 'discard_cleanups'])

def is_destructor(decl):
    return decl.name in destructor_names

# This list is just much too long... we should probably have an
# attribute instead.
special_names = set(['do_final_cleanups', 'discard_final_cleanups',
                     'save_cleanups', 'save_final_cleanups',
                     'restore_cleanups', 'restore_final_cleanups',
                     'exceptions_state_mc_init',
                     'make_my_cleanup2', 'make_final_cleanup', 'all_cleanups',
                     'save_my_cleanups', 'quit_target'])

def needs_special_treatment(decl):
    return decl.name in special_names

# Sometimes we need a new placeholder object that isn't the same as
# anything else.
class Dummy(object):
    def __init__(self, location):
        self.location = location

# A wrapper for a cleanup which has been assigned to a variable.
# This holds the variable and the location.
class Cleanup(object):
    def __init__(self, var, location):
        self.var = var
        self.location = location

# A class representing a master cleanup.  This holds a stack of
# cleanup objects and supports a merging operation.
class MasterCleanup(object):
    # Create a new MasterCleanup object.  OTHER, if given, is a
    # MasterCleanup object to copy.
    def __init__(self, other = None):
        # 'cleanups' is a list of cleanups.  Each element is either a
        # Dummy, for an anonymous cleanup, or a Cleanup, for a cleanup
        # which was assigned to a variable.
        if other is None:
            self.cleanups = []
            self.aliases = {}
        else:
            self.cleanups = other.cleanups[:]
            self.aliases = dict(other.aliases)

    def compare_vars(self, definition, argument):
        if definition == argument:
            return True
        if argument in self.aliases:
            argument = self.aliases[argument]
        if definition in self.aliases:
            definition = self.aliases[definition]
        return definition == argument

    def note_assignment(self, lhs, rhs):
        log('noting assignment %s = %s' % (lhs, rhs), 4)
        self.aliases[lhs] = rhs

    # Merge with another MasterCleanup.
    # Returns True if this resulted in a change to our state.
    def merge(self, other):
        # We do explicit iteration like this so we can easily
        # update the list after the loop.
        counter = -1
        found_named = False
        for counter in range(len(self.cleanups) - 1, -1, -1):
            var = self.cleanups[counter]
            log('merge checking %s' % var, 4)
            # Only interested in named cleanups.
            if isinstance(var, Dummy):
                log('=> merge dummy', 5)
                continue
            # Now see if VAR is found in OTHER.
            if other._find_var(var.var) >= 0:
                log ('=> merge found', 5)
                break
            log('=>merge not found', 5)
            found_named = True
        if found_named and counter < len(self.cleanups) - 1:
            log ('merging to %d' % counter, 4)
            if counter < 0:
                self.cleanups = []
            else:
                self.cleanups = self.cleanups[0:counter]
            return True
        # If SELF is empty but OTHER has some cleanups, then consider
        # that a change as well.
        if len(self.cleanups) == 0 and len(other.cleanups) > 0:
            log('merging non-empty other', 4)
            self.cleanups = other.cleanups[:]
            return True
        return False

    # Push a new constructor onto our stack.  LHS is the
    # left-hand-side of the GimpleCall statement.  It may be None,
    # meaning that this constructor's value wasn't used.
    def push(self, location, lhs):
        if lhs is None:
            obj = Dummy(location)
        else:
            obj = Cleanup(lhs, location)
        log('pushing %s' % lhs, 4)
        idx = self._find_var(lhs)
        if idx >= 0:
            gcc.permerror(location, 'reassigning to known cleanup')
            gcc.inform(self.cleanups[idx].location,
                       'previous assignment is here')
        self.cleanups.append(obj)

    # A helper for merge and pop that finds BACK_TO in self.cleanups,
    # and returns the index, or -1 if not found.
    def _find_var(self, back_to):
        for i in range(len(self.cleanups) - 1, -1, -1):
            if isinstance(self.cleanups[i], Dummy):
                continue
            if self.compare_vars(self.cleanups[i].var, back_to):
                return i
        return -1

    # Pop constructors until we find one matching BACK_TO.
    # This is invoked when we see a do_cleanups call.
    def pop(self, location, back_to):
        log('pop:', 4)
        i = self._find_var(back_to)
        if i >= 0:
            self.cleanups = self.cleanups[0:i]
        else:
            gcc.permerror(location, 'destructor call with unknown argument')

    # Check whether ARG is the current master cleanup.  Return True if
    # all is well.
    def verify(self, location, arg):
        log('verify %s' % arg, 4)
        return (len(self.cleanups) > 0
                and not isinstance(self.cleanups[0], Dummy)
                and self.compare_vars(self.cleanups[0].var, arg))

    # Check whether SELF is empty.
    def isempty(self):
        log('isempty: len = %d' % len(self.cleanups), 4)
        return len(self.cleanups) == 0

    # Emit informational warnings about the cleanup stack.
    def inform(self):
        for item in reversed(self.cleanups):
            gcc.inform(item.location, 'leaked cleanup')

class CleanupChecker:
    def __init__(self, fun):
        self.fun = fun
        self.seen_edges = set()
        self.bad_returns = set()

        # This maps BB indices to a list of master cleanups for the
        # BB.
        self.master_cleanups = {}

    # Pick a reasonable location for the basic block BB.
    def guess_bb_location(self, bb):
        if isinstance(bb.gimple, list):
            for stmt in bb.gimple:
                if stmt.loc:
                    return stmt.loc
        return self.fun.end

    # Compute the master cleanup list for BB.
    # Modifies MASTER_CLEANUP in place.
    def compute_master(self, bb, bb_from, master_cleanup):
        if not isinstance(bb.gimple, list):
            return
        curloc = self.fun.end
        for stmt in bb.gimple:
            if stmt.loc:
                curloc = stmt.loc
            if isinstance(stmt, gcc.GimpleCall) and stmt.fndecl:
                if is_constructor(stmt.fndecl):
                    log('saw constructor %s in bb=%d' % (str(stmt.fndecl), bb.index), 2)
                    self.cleanup_aware = True
                    master_cleanup.push(curloc, stmt.lhs)
                elif is_destructor(stmt.fndecl):
                    if str(stmt.fndecl.name) != 'do_cleanups':
                        self.only_do_cleanups_seen = False
                    log('saw destructor %s in bb=%d, bb_from=%d, argument=%s'
                        % (str(stmt.fndecl.name), bb.index, bb_from, str(stmt.args[0])),
                        2)
                    master_cleanup.pop(curloc, stmt.args[0])
                elif needs_special_treatment(stmt.fndecl):
                    pass
                    # gcc.permerror(curloc, 'function needs special treatment')
            elif isinstance(stmt, gcc.GimpleAssign):
                if isinstance(stmt.lhs, gcc.VarDecl) and isinstance(stmt.rhs[0], gcc.VarDecl):
                    master_cleanup.note_assignment(stmt.lhs, stmt.rhs[0])
            elif isinstance(stmt, gcc.GimpleReturn):
                if self.is_constructor:
                    if not master_cleanup.verify(curloc, stmt.retval):
                        gcc.permerror(curloc,
                                      'constructor does not return master cleanup')
                elif not self.is_special_constructor:
                    if not master_cleanup.isempty():
                        if curloc not in self.bad_returns:
                            gcc.permerror(curloc, 'cleanup stack is not empty at return')
                            self.bad_returns.add(curloc)
                            master_cleanup.inform()

    # Traverse a basic block, updating the master cleanup information
    # and propagating to other blocks.
    def traverse_bbs(self, edge, bb, bb_from, entry_master):
        log('traverse_bbs %d from %d' % (bb.index, bb_from), 1)

        # Propagate the entry MasterCleanup though this block.
        master_cleanup = MasterCleanup(entry_master)
        self.compute_master(bb, bb_from, master_cleanup)

        modified = False
        if bb.index in self.master_cleanups:
            # Merge the newly-computed MasterCleanup into the one we
            # have already computed.  If this resulted in a
            # significant change, then we need to re-propagate.
            modified = self.master_cleanups[bb.index].merge(master_cleanup)
        else:
            self.master_cleanups[bb.index] = master_cleanup
            modified = True

        # EDGE is None for the entry BB.
        if edge is not None:
            # If merging cleanups caused a change, check to see if we
            # have a bad loop.
            if edge in self.seen_edges:
                # This error doesn't really help.
                # if modified:
                #     gcc.permerror(self.guess_bb_location(bb),
                #                   'invalid cleanup use in loop')
                return
            self.seen_edges.add(edge)

        if not modified:
            return

        # Now propagate to successor nodes.
        for edge in bb.succs:
            self.traverse_bbs(edge, edge.dest, bb.index, master_cleanup)

    def check_cleanups(self):
        if not self.fun.cfg or not self.fun.decl:
            return 'ignored'
        if is_destructor(self.fun.decl):
            return 'destructor'
        if needs_special_treatment(self.fun.decl):
            return 'special'

        self.is_constructor = is_constructor(self.fun.decl)
        self.is_special_constructor = not self.is_constructor and str(self.fun.decl.name).find('with_cleanup') > -1
        # Yuck.
        if str(self.fun.decl.name) == 'gdb_xml_create_parser_and_cleanup_1':
            self.is_special_constructor = True

        if self.is_special_constructor:
            gcc.inform(self.fun.start, 'function %s is a special constructor' % (self.fun.decl.name))

        # If we only see do_cleanups calls, and this function is not
        # itself a constructor, then we can convert it easily to RAII.
        self.only_do_cleanups_seen = not self.is_constructor
        # If we ever call a constructor, then we are "cleanup-aware".
        self.cleanup_aware = False

        entry_bb = self.fun.cfg.entry
        master_cleanup = MasterCleanup()
        self.traverse_bbs(None, entry_bb, -1, master_cleanup)
        if want_raii_info and self.only_do_cleanups_seen and self.cleanup_aware:
            gcc.inform(self.fun.decl.location,
                       'function %s could be converted to RAII' % (self.fun.decl.name))
        if self.is_constructor:
            return 'constructor'
        return 'OK'

class CheckerPass(gcc.GimplePass):
    def execute(self, fun):
        if fun.decl:
            log("Starting " + fun.decl.name)
            if show_cfg:
                dot = gccutils.cfg_to_dot(fun.cfg, fun.decl.name)
                gccutils.invoke_dot(dot, name=fun.decl.name)
        checker = CleanupChecker(fun)
        what = checker.check_cleanups()
        if fun.decl:
            log(fun.decl.name + ': ' + what, 2)

ps = CheckerPass(name = 'check-cleanups')
# We need the cfg, but we want a relatively high-level Gimple.
ps.register_after('cfg')
