class_docstr: Gather aliasing informations across nodes
  
  As a result, each node from the module is associated to a set of node or
  Intrinsic to which it *may* alias to.
class_docstr_tok: ["Gather","aliasing","informations","across","nodes","As","a","result",",","each","node","from","the","module","is","associated","to","a","set","of","node","or","Intrinsic","to","which","it","*","may","*","alias","to","."]
docstr: A side effect of computing aliases on a Return is that it updates the
  ``return_alias`` field of current function
  
  >>> from pythran import passmanager
  >>> pm = passmanager.PassManager('demo')
  >>> module = ast.parse('def foo(a, b): return a')
  >>> result = pm.gather(Aliases, module)
  >>> module.body[0].return_alias # doctest: +ELLIPSIS
  <function ...merge_return_aliases at...>
  
  This field is a function that takes as many nodes as the function
  argument count as input and returns an expression based on
  these arguments if the function happens to create aliasing
  between its input and output. In our case:
  
  >>> f = module.body[0].return_alias
  >>> Aliases.dump(f([ast.Name('A', ast.Load(), None, None),
  ...                 ast.Constant(1, None)]))
  ['A']
  
  This also works if the relationship between input and output
  is more complex:
  
  >>> module = ast.parse('def foo(a, b): return a or b[0]')
  >>> result = pm.gather(Aliases, module)
  >>> f = module.body[0].return_alias
  >>> List = ast.List([ast.Name('L0', ast.Load(), None, None)],
  ...                 ast.Load())
  >>> Aliases.dump(f([ast.Name('B', ast.Load(), None, None), List]))
  ['B', '[L0][0]']
  
  Which actually means that when called with two arguments ``B`` and
  the single-element list ``[L[0]]``, ``foo`` may returns either the
  first argument, or the first element of the second argument.
docstr_tok: ["A","side","effect","of","computing","aliases","on","a","Return","is","that","it","updates","the","``","return_alias","``","field","of","current","function",">",">",">","from","pythran","import","passmanager",">",">",">","pm","=","passmanager.PassManager","(","'demo","'",")",">",">",">","module","=","ast.parse","(","'def","foo","(","a",",","b",")",":","return","a","'",")",">",">",">","result","=","pm.gather","(","Aliases",",","module",")",">",">",">","module.body","[","0","]",".return_alias","#","doctest",":","+ELLIPSIS","<","function","...","merge_return_aliases","at","...",">","This","field","is","a","function","that","takes","as","many","nodes","as","the","function","argument","count","as","input","and","returns","an","expression","based","on","these","arguments","if","the","function","happens","to","create","aliasing","between","its","input","and","output",".","In","our","case",":",">",">",">","f","=","module.body","[","0","]",".return_alias",">",">",">","Aliases.dump","(","f","(","[","ast.Name","(","'","A","'",",","ast.Load","(",")",",","None",",","None",")",",","...","ast.Constant","(","1",",","None",")","]",")",")","[","'","A","'","]","This","also","works","if","the","relationship","between","input","and","output","is","more","complex",":",">",">",">","module","=","ast.parse","(","'def","foo","(","a",",","b",")",":","return","a","or","b","[","0","]","'",")",">",">",">","result","=","pm.gather","(","Aliases",",","module",")",">",">",">","f","=","module.body","[","0","]",".return_alias",">",">",">","List","=","ast.List","(","[","ast.Name","(","'L0","'",",","ast.Load","(",")",",","None",",","None",")","]",",","...","ast.Load","(",")",")",">",">",">","Aliases.dump","(","f","(","[","ast.Name","(","'","B","'",",","ast.Load","(",")",",","None",",","None",")",",","List","]",")",")","[","'","B","'",",","'","[","L0","]","[","0","]","'","]","Which","actually","means","that","when","called","with","two","arguments","``","B","``","and","the","single-element","list","``","[","L","[","0","]","]","``",",","``","foo","``","may","returns","either","the","first","argument",",","or","the","first","element","of","the","second","argument","."]
code: def visit_Return(self, node):
      """
      A side effect of computing aliases on a Return is that it updates the
      ``return_alias`` field of current function
  
      >>> from pythran import passmanager
      >>> pm = passmanager.PassManager('demo')
      >>> module = ast.parse('def foo(a, b): return a')
      >>> result = pm.gather(Aliases, module)
      >>> module.body[0].return_alias # doctest: +ELLIPSIS
      <function ...merge_return_aliases at...>
  
      This field is a function that takes as many nodes as the function
      argument count as input and returns an expression based on
      these arguments if the function happens to create aliasing
      between its input and output. In our case:
  
      >>> f = module.body[0].return_alias
      >>> Aliases.dump(f([ast.Name('A', ast.Load(), None, None),
      ...                 ast.Constant(1, None)]))
      ['A']
  
      This also works if the relationship between input and output
      is more complex:
  
      >>> module = ast.parse('def foo(a, b): return a or b[0]')
      >>> result = pm.gather(Aliases, module)
      >>> f = module.body[0].return_alias
      >>> List = ast.List([ast.Name('L0', ast.Load(), None, None)],
      ...                 ast.Load())
      >>> Aliases.dump(f([ast.Name('B', ast.Load(), None, None), List]))
      ['B', '[L0][0]']
  
      Which actually means that when called with two arguments ``B`` and
      the single-element list ``[L[0]]``, ``foo`` may returns either the
      first argument, or the first element of the second argument.
      """
      if not node.value:
          return
      ret_aliases = self.visit(node.value)
      if Aliases.RetId in self.aliases:
          ret_aliases = ret_aliases.union(self.aliases[Aliases.RetId])
      self.aliases[Aliases.RetId] = ret_aliases
  
imports: from pythran.analyses.global_declarations import GlobalDeclarations
  from pythran.intrinsic import Intrinsic, Class, UnboundValue
  from pythran.passmanager import ModuleAnalysis
  from pythran.tables import functions, methods, MODULES
  from pythran.unparse import Unparser
  from pythran.conversion import demangle
  import pythran.metadata
  from pythran.utils import isnum
  from pythran.syntax import PythranSyntaxError
  import gast
  from copy import deepcopy
  from itertools import product
  import io
label_desc: Use image node_id 11 for calling the Aliases obj's underlying member method code with example usage: obj.visit_Return(node) without return types