// gogo.h -- Go frontend parsed representation.     -*- C++ -*-

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef GO_GOGO_H
#define GO_GOGO_H

#include "go-linemap.h"

class Traverse;
class Statement_inserter;
class Type;
class Type_equal;
class Typed_identifier;
class Typed_identifier_list;
class Function_type;
class Expression;
class Expression_list;
class Statement;
class Temporary_statement;
class Block;
class Function;
class Bindings;
class Bindings_snapshot;
class Package;
class Variable;
class Pointer_type;
class Struct_type;
class Struct_field;
class Struct_field_list;
class Array_type;
class Map_type;
class Channel_type;
class Interface_type;
class Named_type;
class Forward_declaration_type;
class Named_object;
class Label;
class Translate_context;
class Backend;
class Export;
class Export_function_body;
class Import;
class Import_function_body;
class Bexpression;
class Btype;
class Bstatement;
class Bblock;
class Bvariable;
class Blabel;
class Bfunction;
class Escape_context;
class Node;

// This file declares the basic classes used to hold the internal
// representation of Go which is built by the parser.

// An initialization function for an imported package.  This is a
// magic function which initializes variables and runs the "init"
// function.

class Import_init
{
 public:
  Import_init(const std::string& package_name, const std::string& init_name,
	      int priority)
    : package_name_(package_name), init_name_(init_name), priority_(priority)
  { }

  // The name of the package being imported.
  const std::string&
  package_name() const
  { return this->package_name_; }

  // The name of the package's init function.
  const std::string&
  init_name() const
  { return this->init_name_; }

  // Older V1 export data uses a priority scheme to order
  // initialization functions; functions with a lower priority number
  // must be run first. This value will be set to -1 for current
  // generation objects, and will take on a non-negative value only
  // when importing a V1-vintage object.
  int
  priority() const
  { return this->priority_; }

  // Reset priority.
  void
  set_priority(int new_priority)
  { this->priority_ = new_priority; }

  // Record the fact that some other init fcn must be run before this init fcn.
  void
  record_precursor_fcn(std::string init_fcn_name)
  { this->precursor_functions_.insert(init_fcn_name); }

  // Return the list of precursor fcns for this fcn (must be run before it).
  const std::set<std::string>&
  precursors() const
  { return this->precursor_functions_; }

  // Whether this is a dummy init, which is used only to record transitive import.
  bool
  is_dummy() const
  { return this->init_name_[0] == '~'; }

 private:
  // The name of the package being imported.
  std::string package_name_;
  // The name of the package's init function.
  std::string init_name_;
  // Names of init functions that must be run before this fcn.
  std::set<std::string> precursor_functions_;
  // Priority for this function. See note above on obsolescence.
  int priority_;
};

// For sorting purposes.

struct Import_init_lt {
  bool operator()(const Import_init* i1, const Import_init* i2) const
  {
    return i1->init_name() < i2->init_name();
  }
};

// Set of import init objects.
class Import_init_set : public std::set<Import_init*, Import_init_lt> {
};

inline bool
priority_compare(const Import_init* i1, const Import_init* i2)
{
  if (i1->priority() < i2->priority())
    return true;
  if (i1->priority() > i2->priority())
    return false;
  if (i1->package_name() != i2->package_name())
    return i1->package_name() < i2->package_name();
  return i1->init_name() < i2->init_name();
}

// The holder for the internal representation of the entire
// compilation unit.

class Gogo
{
 public:
  // Create the IR, passing in the sizes of the types "int" and
  // "uintptr" in bits.
  Gogo(Backend* backend, Linemap *linemap, int int_type_size, int pointer_size);

  // Get the backend generator.
  Backend*
  backend()
  { return this->backend_; }

  // Get the Location generator.
  Linemap*
  linemap()
  { return this->linemap_; }

  // Get the package name.
  const std::string&
  package_name() const;

  // Set the package name.
  void
  set_package_name(const std::string&, Location);

  // Return whether this is the "main" package.
  bool
  is_main_package() const;

  // If necessary, adjust the name to use for a hidden symbol.  We add
  // the package name, so that hidden symbols in different packages do
  // not collide.
  std::string
  pack_hidden_name(const std::string& name, bool is_exported) const
  {
    return (is_exported
	    ? name
	    : '.' + this->pkgpath() + '.' + name);
  }

  // Unpack a name which may have been hidden.  Returns the
  // user-visible name of the object.
  static std::string
  unpack_hidden_name(const std::string& name)
  { return name[0] != '.' ? name : name.substr(name.rfind('.') + 1); }

  // Return whether a possibly packed name is hidden.
  static bool
  is_hidden_name(const std::string& name)
  { return name[0] == '.'; }

  // Return the package path of a hidden name.
  static std::string
  hidden_name_pkgpath(const std::string& name)
  {
    go_assert(Gogo::is_hidden_name(name));
    return name.substr(1, name.rfind('.') - 1);
  }

  // Given a name which may or may not have been hidden, append the
  // appropriate version of the name to the result string.
  static void
  append_possibly_hidden_name(std::string *result, const std::string& name);

  // Given a name which may or may not have been hidden, return the
  // name to use in an error message.
  static std::string
  message_name(const std::string& name);

  // Return whether a name is the blank identifier _.
  static bool
  is_sink_name(const std::string& name)
  {
    return (name[0] == '.'
	    && name[name.length() - 1] == '_'
	    && name[name.length() - 2] == '.')
        || (name[0] == '_'
            && name.length() == 1);
  }

  // Helper used when adding parameters (including receiver param) to the
  // bindings of a function. If the specified parameter name is empty or
  // corresponds to the sink name, param name is replaced with a new unique
  // name. PNAME is the address of a string containing the parameter variable
  // name to be checked/updated; TAG is a descriptive tag to be used in
  // manufacturing the new unique name, and COUNT is the address of a counter
  // holding the number of params renamed so far with the tag in question.
  static void
  rename_if_empty(std::string* pname, const char* tag, unsigned* count);

  // Convert a pkgpath into a string suitable for a symbol
  static std::string
  pkgpath_for_symbol(const std::string& pkgpath);

  // Compute a hash code for a string, given a seed.
  static unsigned int
  hash_string(const std::string&, unsigned int);

  // Return the package path to use for reflect.Type.PkgPath.
  const std::string&
  pkgpath() const;

  // Return the package path to use for a symbol name.
  const std::string&
  pkgpath_symbol() const;

  // Set the package path from a command line option.
  void
  set_pkgpath(const std::string&);

  // Set the prefix from a command line option.
  void
  set_prefix(const std::string&);

  // Return whether pkgpath was set from a command line option.
  bool
  pkgpath_from_option() const
  { return this->pkgpath_from_option_; }

  // Return the relative import path as set from the command line.
  // Returns an empty string if it was not set.
  const std::string&
  relative_import_path() const
  { return this->relative_import_path_; }

  // Set the relative import path from a command line option.
  void
  set_relative_import_path(const std::string& s)
  { this->relative_import_path_ = s; }

  // Set the C header file to write.  This is used for the runtime
  // package.
  void
  set_c_header(const std::string& s)
  { this->c_header_ = s; }

  // Return whether to check for division by zero in binary operations.
  bool
  check_divide_by_zero() const
  { return this->check_divide_by_zero_; }

  // Set the option to check division by zero from a command line option.
  void
  set_check_divide_by_zero(bool b)
  { this->check_divide_by_zero_ = b; }

  // Return whether to check for division overflow in binary operations.
  bool
  check_divide_overflow() const
  { return this->check_divide_overflow_; }

  // Set the option to check division overflow from a command line option.
  void
  set_check_divide_overflow(bool b)
  { this->check_divide_overflow_ = b; }

  // Return whether we are compiling the runtime package.
  bool
  compiling_runtime() const
  { return this->compiling_runtime_; }

  // Set whether we are compiling the runtime package.
  void
  set_compiling_runtime(bool b)
  { this->compiling_runtime_ = b; }

  // Return the level of escape analysis debug information to emit.
  int
  debug_escape_level() const
  { return this->debug_escape_level_; }

  // Set the level of escape analysis debugging from a command line option.
  void
  set_debug_escape_level(int level)
  { this->debug_escape_level_ = level; }

  // Return the hash for debug escape analysis.
  std::string
  debug_escape_hash() const
  { return this->debug_escape_hash_; }

  // Set the hash value for debug escape analysis.
  void
  set_debug_escape_hash(const std::string& s)
  { this->debug_escape_hash_ = s; }

  // Return whether to output optimization diagnostics.
  bool
  debug_optimization() const
  { return this->debug_optimization_; }

  // Set the option to output optimization diagnostics.
  void
  set_debug_optimization(bool b)
  { this->debug_optimization_ = b; }

  // Dump to stderr for debugging
  void debug_dump();

  // Return the size threshold used to determine whether to issue
  // a nil-check for a given pointer dereference. A threshold of -1
  // implies that all potentially faulting dereference ops should
  // be nil-checked. A positive threshold of N implies that a deref
  // of *P where P has size less than N doesn't need a nil check.
  int64_t
  nil_check_size_threshold() const
  { return this->nil_check_size_threshold_; }

  // Set the nil-check size threshold, as described above.
  void
  set_nil_check_size_threshold(int64_t bytes)
  { this->nil_check_size_threshold_ = bytes; }

  // Import a package.  FILENAME is the file name argument, LOCAL_NAME
  // is the local name to give to the package.  If LOCAL_NAME is empty
  // the declarations are added to the global scope.
  void
  import_package(const std::string& filename, const std::string& local_name,
		 bool is_local_name_exported, bool must_exist, Location);

  // Whether we are the global binding level.
  bool
  in_global_scope() const;

  // Look up a name in the current binding contours.
  Named_object*
  lookup(const std::string&, Named_object** pfunction) const;

  // Look up a name in the current block.
  Named_object*
  lookup_in_block(const std::string&) const;

  // Look up a name in the global namespace--the universal scope.
  Named_object*
  lookup_global(const char*) const;

  // Add a new imported package.  REAL_NAME is the real name of the
  // package.  ALIAS is the alias of the package; this may be the same
  // as REAL_NAME.  This sets *PADD_TO_GLOBALS if symbols added to
  // this package should be added to the global namespace; this is
  // true if the alias is ".".  LOCATION is the location of the import
  // statement.  This returns the new package, or NULL on error.
  Package*
  add_imported_package(const std::string& real_name, const std::string& alias,
		       bool is_alias_exported,
		       const std::string& pkgpath,
		       const std::string& pkgpath_symbol,
		       Location location,
		       bool* padd_to_globals);

  // Register a package.  This package may or may not be imported.
  // This returns the Package structure for the package, creating if
  // it necessary.
  Package*
  register_package(const std::string& pkgpath,
		   const std::string& pkgpath_symbol, Location);

  // Look up a package by pkgpath, and return its pkgpath_symbol.
  std::string
  pkgpath_symbol_for_package(const std::string&);

  // Start compiling a function.  ADD_METHOD_TO_TYPE is true if a
  // method function should be added to the type of its receiver.
  Named_object*
  start_function(const std::string& name, Function_type* type,
		 bool add_method_to_type, Location);

  // Finish compiling a function.
  void
  finish_function(Location);

  // Return the current function.
  Named_object*
  current_function() const;

  // Return the current block.
  Block*
  current_block();

  // Start a new block.  This is not initially associated with a
  // function.
  void
  start_block(Location);

  // Finish the current block and return it.
  Block*
  finish_block(Location);

  // Declare an erroneous name.  This is used to avoid knock-on errors
  // after a parsing error.
  Named_object*
  add_erroneous_name(const std::string& name);

  // Declare an unknown name.  This is used while parsing.  The name
  // must be resolved by the end of the parse.  Unknown names are
  // always added at the package level.
  Named_object*
  add_unknown_name(const std::string& name, Location);

  // Declare a function.
  Named_object*
  declare_function(const std::string&, Function_type*, Location);

  // Declare a function at the package level.  This is used for
  // functions generated for a type.
  Named_object*
  declare_package_function(const std::string&, Function_type*, Location);

  // Add a function declaration to the list of functions we may want
  // to inline.
  void
  add_imported_inlinable_function(Named_object*);

  // Add a function to the list of functions that we do want to
  // inline.
  void
  add_imported_inline_function(Named_object* no)
  { this->imported_inline_functions_.push_back(no); }

  // Add a label.
  Label*
  add_label_definition(const std::string&, Location);

  // Add a label reference.  ISSUE_GOTO_ERRORS is true if we should
  // report errors for a goto from the current location to the label
  // location.
  Label*
  add_label_reference(const std::string&, Location,
		      bool issue_goto_errors);

  // An analysis set is a list of functions paired with a boolean that indicates
  // whether the list of functions are recursive.
  typedef std::pair<std::vector<Named_object*>, bool> Analysis_set;

  // Add a GROUP of possibly RECURSIVE functions to the Analysis_set for this
  // package.
  void
  add_analysis_set(const std::vector<Named_object*>& group, bool recursive)
  { this->analysis_sets_.push_back(std::make_pair(group, recursive)); }

  // Return a snapshot of the current binding state.
  Bindings_snapshot*
  bindings_snapshot(Location);

  // Add a statement to the current block.
  void
  add_statement(Statement*);

  // Add a block to the current block.
  void
  add_block(Block*, Location);

  // Add a constant.
  Named_object*
  add_constant(const Typed_identifier&, Expression*, int iota_value);

  // Add a type.
  void
  add_type(const std::string&, Type*, Location);

  // Add a named type.  This is used for builtin types, and to add an
  // imported type to the global scope.
  void
  add_named_type(Named_type*);

  // Declare a type.
  Named_object*
  declare_type(const std::string&, Location);

  // Declare a type at the package level.  This is used when the
  // parser sees an unknown name where a type name is required.
  Named_object*
  declare_package_type(const std::string&, Location);

  // Define a type which was already declared.
  void
  define_type(Named_object*, Named_type*);

  // Add a variable.
  Named_object*
  add_variable(const std::string&, Variable*);

  // Add a sink--a reference to the blank identifier _.
  Named_object*
  add_sink();

  // Add a type which needs to be verified.  This is used for sink
  // types, just to give appropriate error messages.
  void
  add_type_to_verify(Type* type);

  // Add a named object to the current namespace.  This is used for
  // import . "package".
  void
  add_dot_import_object(Named_object*);

  // Add an identifier to the list of names seen in the file block.
  void
  add_file_block_name(const std::string& name, Location location)
  { this->file_block_names_[name] = location; }

  // Add a linkname, from the go:linkname compiler directive.  This
  // changes the externally visible name of GO_NAME to be EXT_NAME.
  // If EXT_NAME is the empty string, GO_NAME is unchanged, but the
  // symbol is made publicly visible.
  void
  add_linkname(const std::string& go_name, bool is_exported,
	       const std::string& ext_name, Location location);

  // Mark all local variables in current bindings as used.  This is
  // used when there is a parse error to avoid useless errors.
  void
  mark_locals_used();

  // Note that we've seen an interface type.  This is used to build
  // all required interface method tables.
  void
  record_interface_type(Interface_type*);

  // Note that we need an initialization function.
  void
  set_need_init_fn()
  { this->need_init_fn_ = true; }

  // Return whether the current file imported the unsafe package.
  bool
  current_file_imported_unsafe() const
  { return this->current_file_imported_unsafe_; }

  // Clear out all names in file scope.  This is called when we start
  // parsing a new file.
  void
  clear_file_scope();

  // Record that VAR1 must be initialized after VAR2.  This is used
  // when VAR2 does not appear in VAR1's INIT or PREINIT.
  void
  record_var_depends_on(Variable* var1, Named_object* var2)
  {
    go_assert(this->var_deps_.find(var1) == this->var_deps_.end());
    this->var_deps_[var1] = var2;
  }

  // Return the variable that VAR depends on, or NULL if none.
  Named_object*
  var_depends_on(Variable* var) const
  {
    Var_deps::const_iterator p = this->var_deps_.find(var);
    return p != this->var_deps_.end() ? p->second : NULL;
  }

  // Queue up a type-specific hash function to be written out.  This
  // is used when a type-specific hash function is needed when not at
  // top level.
  void
  queue_hash_function(Type* type, int64_t size, const std::string& hash_name,
		      Function_type* hash_fntype);

  // Queue up a type-specific equal function to be written out.  This
  // is used when a type-specific equal function is needed when not at
  // top level.
  void
  queue_equal_function(Type* type, Named_type* name, int64_t size,
		       const std::string& equal_name,
		       Function_type* equal_fntype);

  // Write out queued specific type functions.
  void
  write_specific_type_functions();

  // Whether we are done writing out specific type functions.
  bool
  specific_type_functions_are_written() const
  { return this->specific_type_functions_are_written_; }

  // Add a pointer that needs to be added to the list of objects
  // traversed by the garbage collector.  This should be an expression
  // of pointer type that points to static storage.  It's not
  // necessary to add global variables to this list, just global
  // variable initializers that would otherwise not be seen.
  void
  add_gc_root(Expression* expr)
  {
    this->set_need_init_fn();
    this->gc_roots_.push_back(expr);
  }

  // Add a type to the descriptor list.
  void
  add_type_descriptor(Type* type)
  { this->type_descriptors_.push_back(type); }

  // Traverse the tree.  See the Traverse class.
  void
  traverse(Traverse*);

  // Define the predeclared global names.
  void
  define_global_names();

  // Verify and complete all types.
  void
  verify_types();

  // Lower the parse tree.
  void
  lower_parse_tree();

  // Lower all the statements in a block.
  void
  lower_block(Named_object* function, Block*);

  // Lower an expression.
  void
  lower_expression(Named_object* function, Statement_inserter*, Expression**);

  // Lower a constant.
  void
  lower_constant(Named_object*);

  // Flatten all the statements in a block.
  void
  flatten_block(Named_object* function, Block*);

  // Flatten an expression.
  void
  flatten_expression(Named_object* function, Statement_inserter*, Expression**);

  // Create all necessary function descriptors.
  void
  create_function_descriptors();

  // Finalize the method lists and build stub methods for named types.
  void
  finalize_methods();

  // Finalize the method list for one type.
  void
  finalize_methods_for_type(Type*);

  // Work out the types to use for unspecified variables and
  // constants.
  void
  determine_types();

  // Type check the program.
  void
  check_types();

  // Check the types in a single block.  This is used for complicated
  // go statements.
  void
  check_types_in_block(Block*);

  // Check for return statements.
  void
  check_return_statements();

  // Remove deadcode.
  void
  remove_deadcode();

  // Make implicit type conversions explicit.
  void
  add_conversions();

  // Make implicit type conversions explicit in a block.
  void
  add_conversions_in_block(Block*);

  // Analyze the program flow for escape information.
  void
  analyze_escape();

  // Discover the groups of possibly recursive functions in this package.
  void
  discover_analysis_sets();

  // Build a connectivity graph between the objects in each analyzed function.
  void
  assign_connectivity(Escape_context*, Named_object*);

  // Traverse the objects in the connecitivty graph from the sink, adjusting the
  // escape levels of each object.
  void
  propagate_escape(Escape_context*, Node*);

  // Add notes about the escape level of a function's input and output
  // parameters for exporting and importing top level functions.
  void
  tag_function(Escape_context*, Named_object*);

  // Reclaim memory of escape analysis Nodes.
  void
  reclaim_escape_nodes();

  // Do all exports.
  void
  do_exports();

  // Add an import control function for an imported package to the
  // list.
  void
  add_import_init_fn(const std::string& package_name,
		     const std::string& init_name, int prio);

  // Return the Import_init for a given init name.
  Import_init*
  lookup_init(const std::string& init_name);

  // Turn short-cut operators (&&, ||) into explicit if statements.
  void
  remove_shortcuts();

  // Turn short-cut operators into explicit if statements in a block.
  void
  remove_shortcuts_in_block(Block*);

  // Use temporary variables to force order of evaluation.
  void
  order_evaluations();

  // Order evaluations in a block.
  void
  order_block(Block*);

  // Add write barriers as needed.
  void
  add_write_barriers();

  // Return whether an assignment that sets LHS to RHS needs a write
  // barrier.
  bool
  assign_needs_write_barrier(Expression* lhs,
                             Unordered_set(const Named_object*)*);

  // Return whether EXPR is the address of a variable that can be set
  // without a write barrier.  That is, if this returns true, then an
  // assignment to *EXPR does not require a write barrier.
  bool
  is_nonwb_pointer(Expression* expr, Unordered_set(const Named_object*)*);

  // Return an assignment that sets LHS to RHS using a write barrier.
  // This returns an if statement that checks whether write barriers
  // are enabled.  If not, it does LHS = RHS, otherwise it calls the
  // appropriate write barrier function.
  Statement*
  assign_with_write_barrier(Function*, Block*, Statement_inserter*,
			    Expression* lhs, Expression* rhs, Location);

  // Return a statement that tests whether write barriers are enabled
  // and executes either the efficient code (WITHOUT) or the write
  // barrier function call (WITH), depending.
  Statement*
  check_write_barrier(Block*, Statement* without, Statement* with);

  // Flatten parse tree.
  void
  flatten();

  // Build thunks for functions which call recover.
  void
  build_recover_thunks();

  // Simplify statements which might use thunks: go and defer
  // statements.
  void
  simplify_thunk_statements();

  // Dump AST if -fgo-dump-ast is set.
  void
  dump_ast(const char* basename);

  // Dump Call Graph if -fgo-dump-calls is set.
  void
  dump_call_graph(const char* basename);

  // Dump Connection Graphs if -fgo-dump-connections is set.
  void
  dump_connection_graphs(const char* basename);

  // Convert named types to the backend representation.
  void
  convert_named_types();

  // Convert named types in a list of bindings.
  void
  convert_named_types_in_bindings(Bindings*);

  // True if named types have been converted to the backend
  // representation.
  bool
  named_types_are_converted() const
  { return this->named_types_are_converted_; }

  // Give an error if the initialization of VAR depends on itself.
  void
  check_self_dep(Named_object*);

  // Write out the global values.
  void
  write_globals();

  // Build required interface method tables.
  void
  build_interface_method_tables();

  // Return an expression which allocates memory to hold values of type TYPE.
  Expression*
  allocate_memory(Type *type, Location);

  // Return the assembler name to use for an exported function, a
  // method, or a function/method declaration.
  std::string
  function_asm_name(const std::string& go_name, const Package*,
		    const Type* receiver);

  // Return the name to use for a function descriptor.
  std::string
  function_descriptor_name(Named_object*);

  // Return the name to use for a generated stub method.
  std::string
  stub_method_name(const Package*, const std::string& method_name);

  // Return the name of the hash function for TYPE.
  std::string
  hash_function_name(const Type*);

  // Return the name of the equal function for TYPE.
  std::string
  equal_function_name(const Type*, const Named_type*);

  // Return the assembler name to use for a global variable.
  std::string
  global_var_asm_name(const std::string& go_name, const Package*);

  // Return a name to use for an error case.  This should only be used
  // after reporting an error, and is used to avoid useless knockon
  // errors.
  static std::string
  erroneous_name();

  // Return whether the name indicates an error.
  static bool
  is_erroneous_name(const std::string&);

  // Return a name to use for a thunk function.  A thunk function is
  // one we create during the compilation, for a go statement or a
  // defer statement or a method expression.
  std::string
  thunk_name();

  // Return whether an object is a thunk.
  static bool
  is_thunk(const Named_object*);

  // Return the name to use for an init function.
  std::string
  init_function_name();

  // Return the name to use for a nested function.
  std::string
  nested_function_name(Named_object* enclosing);

  // Return the name to use for a sink funciton.
  std::string
  sink_function_name();

  // Return the name to use for an (erroneous) redefined function.
  std::string
  redefined_function_name();

  // Return the name for use for a recover thunk.
  std::string
  recover_thunk_name(const std::string& name, const Type* rtype);

  // Return the name to use for the GC root variable.
  std::string
  gc_root_name();

  // Return the name to use for a composite literal or string
  // initializer.
  std::string
  initializer_name();

  // Return the name of the variable used to represent the zero value
  // of a map.
  std::string
  map_zero_value_name();

  // Get the name of the magic initialization function.
  const std::string&
  get_init_fn_name();

  // Return the name for a dummy init function, which is not a real
  // function but only for tracking transitive import.
  std::string
  dummy_init_fn_name();

  // Return the package path symbol from an init function name, which
  // can be a real init function or a dummy one.
  std::string
  pkgpath_from_init_fn_name(std::string);

  // Return the name for a type descriptor symbol.
  std::string
  type_descriptor_name(const Type*, Named_type*);

  // Return the name of the type descriptor list symbol of a package.
  std::string
  type_descriptor_list_symbol(const std::string&);

  // Return the name of the list of all type descriptor lists.
  std::string
  typelists_symbol();

  // Return the assembler name for the GC symbol for a type.
  std::string
  gc_symbol_name(Type*);

  // Return the assembler name for a ptrmask variable.
  std::string
  ptrmask_symbol_name(const std::string& ptrmask_sym_name);

  // Return the name to use for an interface method table.
  std::string
  interface_method_table_name(Interface_type*, Type*, bool is_pointer);

  // Return whether NAME is a special name that can not be passed to
  // unpack_hidden_name.  This is needed because various special names
  // use "..SUFFIX", but unpack_hidden_name just looks for '.'.
  static bool
  is_special_name(const std::string& name);

 private:
  // During parsing, we keep a stack of functions.  Each function on
  // the stack is one that we are currently parsing.  For each
  // function, we keep track of the current stack of blocks.
  struct Open_function
  {
    // The function.
    Named_object* function;
    // The stack of active blocks in the function.
    std::vector<Block*> blocks;
  };

  // The stack of functions.
  typedef std::vector<Open_function> Open_functions;

  // Set up the built-in unsafe package.
  void
  import_unsafe(const std::string&, bool is_exported, Location);

  // Return the current binding contour.
  Bindings*
  current_bindings();

  const Bindings*
  current_bindings() const;

  void
  write_c_header();

  // Get the decl for the magic initialization function.
  Named_object*
  initialization_function_decl();

  // Create the magic initialization function.
  Named_object*
  create_initialization_function(Named_object* fndecl, Bstatement* code_stmt);

  // Initialize imported packages. BFUNCTION is the function
  // into which the package init calls will be placed.
  void
  init_imports(std::vector<Bstatement*>&, Bfunction* bfunction);

  // Register variables with the garbage collector.
  void
  register_gc_vars(const std::vector<Named_object*>&,
                   std::vector<Bstatement*>&,
                   Bfunction* init_bfunction);

  // Build the list of type descriptors.
  void
  build_type_descriptor_list();

  // Register the type descriptors with the runtime.
  void
  register_type_descriptors(std::vector<Bstatement*>&,
                            Bfunction* init_bfunction);

  void
  propagate_writebarrierrec();

  Named_object*
  write_barrier_variable();

  // Type used to map import names to packages.
  typedef std::map<std::string, Package*> Imports;

  // Type used to map package names to packages.
  typedef std::map<std::string, Package*> Packages;

  // Type used to map variables to the function calls that set them.
  // This is used for initialization dependency analysis.
  typedef std::map<Variable*, Named_object*> Var_deps;

  // Type used to map identifiers in the file block to the location
  // where they were defined.
  typedef Unordered_map(std::string, Location) File_block_names;

  // Type used to queue writing a type specific function.
  struct Specific_type_function
  {
    enum Specific_type_function_kind { SPECIFIC_HASH, SPECIFIC_EQUAL };

    Type* type;
    Named_type* name;
    int64_t size;
    Specific_type_function_kind kind;
    std::string fnname;
    Function_type* fntype;

    Specific_type_function(Type* atype, Named_type* aname, int64_t asize,
			   Specific_type_function_kind akind,
			   const std::string& afnname,
			   Function_type* afntype)
      : type(atype), name(aname), size(asize), kind(akind),
	fnname(afnname), fntype(afntype)
    { }
  };

  // Recompute init priorities.
  void
  recompute_init_priorities();

  // Recursive helper used by the routine above.
  void
  update_init_priority(Import_init* ii,
                       std::set<const Import_init *>* visited);

  // The backend generator.
  Backend* backend_;
  // The object used to keep track of file names and line numbers.
  Linemap* linemap_;
  // The package we are compiling.
  Package* package_;
  // The list of currently open functions during parsing.
  Open_functions functions_;
  // The global binding contour.  This includes the builtin functions
  // and the package we are compiling.
  Bindings* globals_;
  // The list of names we have seen in the file block.
  File_block_names file_block_names_;
  // Mapping from import file names to packages.
  Imports imports_;
  // Whether the magic unsafe package was imported.
  bool imported_unsafe_;
  // Whether the magic unsafe package was imported by the current file.
  bool current_file_imported_unsafe_;
  // Mapping from package names we have seen to packages.  This does
  // not include the package we are compiling.
  Packages packages_;
  // The functions named "init", if there are any.
  std::vector<Named_object*> init_functions_;
  // A mapping from variables to the function calls that initialize
  // them, if it is not stored in the variable's init or preinit.
  // This is used for dependency analysis.
  Var_deps var_deps_;
  // Whether we need a magic initialization function.
  bool need_init_fn_;
  // The name of the magic initialization function.
  std::string init_fn_name_;
  // A list of import control variables for packages that we import.
  Import_init_set imported_init_fns_;
  // The package path used for reflection data.
  std::string pkgpath_;
  // The package path to use for a symbol name.
  std::string pkgpath_symbol_;
  // The prefix to use for symbols, from the -fgo-prefix option.
  std::string prefix_;
  // Whether pkgpath_ has been set.
  bool pkgpath_set_;
  // Whether an explicit package path was set by -fgo-pkgpath.
  bool pkgpath_from_option_;
  // Whether an explicit prefix was set by -fgo-prefix.
  bool prefix_from_option_;
  // The relative import path, from the -fgo-relative-import-path
  // option.
  std::string relative_import_path_;
  // The C header file to write, from the -fgo-c-header option.
  std::string c_header_;
  // Whether or not to check for division by zero, from the
  // -fgo-check-divide-zero option.
  bool check_divide_by_zero_;
  // Whether or not to check for division overflow, from the
  // -fgo-check-divide-overflow option.
  bool check_divide_overflow_;
  // Whether we are compiling the runtime package, from the
  // -fgo-compiling-runtime option.
  bool compiling_runtime_;
  // The level of escape analysis debug information to emit, from the
  // -fgo-debug-escape option.
  int debug_escape_level_;
  // A hash value for debug escape analysis, from the
  // -fgo-debug-escape-hash option. The analysis is run only on
  // functions with names that hash to the matching value.
  std::string debug_escape_hash_;
  // Whether to output optimization diagnostics, from the
  // -fgo-debug-optimization option.
  bool debug_optimization_;
  // Nil-check size threshhold.
  int64_t nil_check_size_threshold_;
  // A list of types to verify.
  std::vector<Type*> verify_types_;
  // A list of interface types defined while parsing.
  std::vector<Interface_type*> interface_types_;
  // Type specific functions to write out.
  std::vector<Specific_type_function*> specific_type_functions_;
  // Whether we are done writing out specific type functions.
  bool specific_type_functions_are_written_;
  // Whether named types have been converted.
  bool named_types_are_converted_;
  // A list containing groups of possibly mutually recursive functions to be
  // considered during escape analysis.
  std::vector<Analysis_set> analysis_sets_;
  // A list of objects to add to the GC roots.
  std::vector<Expression*> gc_roots_;
  // A list of type descriptors that we need to register.
  std::vector<Type*> type_descriptors_;
  // A list of function declarations with imported bodies that we may
  // want to inline.
  std::vector<Named_object*> imported_inlinable_functions_;
  // A list of functions that we want to inline.  These will be sent
  // to the backend.
  std::vector<Named_object*> imported_inline_functions_;
};

// A block of statements.

class Block
{
 public:
  Block(Block* enclosing, Location);

  // Return the enclosing block.
  const Block*
  enclosing() const
  { return this->enclosing_; }

  // Return the bindings of the block.
  Bindings*
  bindings()
  { return this->bindings_; }

  const Bindings*
  bindings() const
  { return this->bindings_; }

  // Look at the block's statements.
  const std::vector<Statement*>*
  statements() const
  { return &this->statements_; }

  // Return the start location.  This is normally the location of the
  // left curly brace which starts the block.
  Location
  start_location() const
  { return this->start_location_; }

  // Return the end location.  This is normally the location of the
  // right curly brace which ends the block.
  Location
  end_location() const
  { return this->end_location_; }

  // Add a statement to the block.
  void
  add_statement(Statement*);

  // Add a statement to the front of the block.
  void
  add_statement_at_front(Statement*);

  // Replace a statement in a block.
  void
  replace_statement(size_t index, Statement*);

  // Add a Statement before statement number INDEX.
  void
  insert_statement_before(size_t index, Statement*);

  // Add a Statement after statement number INDEX.
  void
  insert_statement_after(size_t index, Statement*);

  // Set the end location of the block.
  void
  set_end_location(Location location)
  { this->end_location_ = location; }

  // Traverse the tree.
  int
  traverse(Traverse*);

  // Set final types for unspecified variables and constants.
  void
  determine_types();

  // Return true if execution of this block may fall through to the
  // next block.
  bool
  may_fall_through() const;

  // Write the export data for the block's statements to the string.
  void
  export_block(Export_function_body*);

  // Turn exported block data into a block.
  static bool
  import_block(Block*, Import_function_body*, Location);

  // Convert the block to the backend representation.
  Bblock*
  get_backend(Translate_context*);

  // Iterate over statements.

  typedef std::vector<Statement*>::iterator iterator;

  iterator
  begin()
  { return this->statements_.begin(); }

  iterator
  end()
  { return this->statements_.end(); }

 private:
  // Enclosing block.
  Block* enclosing_;
  // Statements in the block.
  std::vector<Statement*> statements_;
  // Binding contour.
  Bindings* bindings_;
  // Location of start of block.
  Location start_location_;
  // Location of end of block.
  Location end_location_;
};

// A function.

class Function
{
 public:
  Function(Function_type* type, Named_object*, Block*, Location);

  // Return the function's type.
  Function_type*
  type() const
  { return this->type_; }

  // Return the enclosing function if there is one.
  Named_object*
  enclosing() const
  { return this->enclosing_; }

  // Set the enclosing function.  This is used when building thunks
  // for functions which call recover.
  void
  set_enclosing(Named_object* enclosing)
  {
    go_assert(this->enclosing_ == NULL);
    this->enclosing_ = enclosing;
  }

  // The result variables.
  typedef std::vector<Named_object*> Results;

  // Create the result variables in the outer block.
  void
  create_result_variables(Gogo*);

  // Update the named result variables when cloning a function which
  // calls recover.
  void
  update_result_variables();

  // Return the result variables.
  Results*
  result_variables()
  { return this->results_; }

  bool
  is_sink() const
  { return this->is_sink_; }

  void
  set_is_sink()
  { this->is_sink_ = true; }

  // Whether the result variables have names.
  bool
  results_are_named() const
  { return this->results_are_named_; }

  // Return the assembler name.
  const std::string&
  asm_name() const
  { return this->asm_name_; }

  // Set the assembler name.
  void
  set_asm_name(const std::string& asm_name)
  { this->asm_name_ = asm_name; }

  // Mark this symbol as exported by a linkname directive.
  void
  set_is_exported_by_linkname()
  { this->is_exported_by_linkname_ = true; }

  // Return the pragmas for this function.
  unsigned int
  pragmas() const
  { return this->pragmas_; }

  // Set the pragmas for this function.
  void
  set_pragmas(unsigned int pragmas)
  {
    this->pragmas_ = pragmas;
  }

  // Return the index to use for a nested function.
  unsigned int
  next_nested_function_index()
  {
    ++this->nested_functions_;
    return this->nested_functions_;
  }

  // Whether this method should not be included in the type
  // descriptor.
  bool
  nointerface() const;

  // Record that this method should not be included in the type
  // descriptor.
  void
  set_nointerface();

  // Record that this function is a stub method created for an unnamed
  // type.
  void
  set_is_unnamed_type_stub_method()
  {
    go_assert(this->is_method());
    this->is_unnamed_type_stub_method_ = true;
  }

  // Return the amount of enclosed variables in this closure.
  size_t
  closure_field_count() const
  { return this->closure_fields_.size(); }

  // Add a new field to the closure variable.
  void
  add_closure_field(Named_object* var, Location loc)
  { this->closure_fields_.push_back(std::make_pair(var, loc)); }

  // Whether this function needs a closure.
  bool
  needs_closure() const
  { return !this->closure_fields_.empty(); }

  // Return the closure variable, creating it if necessary.  This is
  // passed to the function as a static chain parameter.
  Named_object*
  closure_var();

  // Set the closure variable.  This is used when building thunks for
  // functions which call recover.
  void
  set_closure_var(Named_object* v)
  {
    go_assert(this->closure_var_ == NULL);
    this->closure_var_ = v;
  }

  // Return the variable for a reference to field INDEX in the closure
  // variable.
  Named_object*
  enclosing_var(unsigned int index)
  {
    go_assert(index < this->closure_fields_.size());
    return closure_fields_[index].first;
  }

  // Set the type of the closure variable if there is one.
  void
  set_closure_type();

  // Get the block of statements associated with the function.
  Block*
  block() const
  { return this->block_; }

  // Get the location of the start of the function.
  Location
  location() const
  { return this->location_; }

  // Return whether this function is actually a method.
  bool
  is_method() const;

  // Add a label definition to the function.
  Label*
  add_label_definition(Gogo*, const std::string& label_name, Location);

  // Add a label reference to a function.  ISSUE_GOTO_ERRORS is true
  // if we should report errors for a goto from the current location
  // to the label location.
  Label*
  add_label_reference(Gogo*, const std::string& label_name,
		      Location, bool issue_goto_errors);

  // Warn about labels that are defined but not used.
  void
  check_labels() const;

  // Note that a new local type has been added.  Return its index.
  unsigned int
  new_local_type_index()
  { return this->local_type_count_++; }

  // Whether this function calls the predeclared recover function.
  bool
  calls_recover() const
  { return this->calls_recover_; }

  // Record that this function calls the predeclared recover function.
  // This is set during the lowering pass.
  void
  set_calls_recover()
  { this->calls_recover_ = true; }

  // Whether this is a recover thunk function.
  bool
  is_recover_thunk() const
  { return this->is_recover_thunk_; }

  // Record that this is a thunk built for a function which calls
  // recover.
  void
  set_is_recover_thunk()
  { this->is_recover_thunk_ = true; }

  // Whether this function already has a recover thunk.
  bool
  has_recover_thunk() const
  { return this->has_recover_thunk_; }

  // Record that this function already has a recover thunk.
  void
  set_has_recover_thunk()
  { this->has_recover_thunk_ = true; }

  // Record that this function is a thunk created for a defer
  // statement that calls the __go_set_defer_retaddr runtime function.
  void
  set_calls_defer_retaddr()
  { this->calls_defer_retaddr_ = true; }

  // Whether this is a type hash or equality function created by the
  // compiler.
  bool
  is_type_specific_function()
  { return this->is_type_specific_function_; }

  // Record that this function is a type hash or equality function
  // created by the compiler.
  void
  set_is_type_specific_function()
  { this->is_type_specific_function_ = true; }

  // Mark the function as going into a unique section.
  void
  set_in_unique_section()
  { this->in_unique_section_ = true; }

  // Return whether this function should be exported for inlining.
  bool
  export_for_inlining() const
  { return this->export_for_inlining_; }

  // Mark the function to be exported for inlining.
  void
  set_export_for_inlining()
  { this->export_for_inlining_ = true; }

  // Return whether this function is inline only.
  bool
  is_inline_only() const
  { return this->is_inline_only_; }

  // Mark the function as inline only: the body should not be emitted
  // if it is not inlined.
  void
  set_is_inline_only()
  { this->is_inline_only_ = true; }

  // Report whether the function is referenced by an inline body.
  bool
  is_referenced_by_inline() const
  { return this->is_referenced_by_inline_; }

  // Mark the function as referenced by an inline body.
  void
  set_is_referenced_by_inline()
  { this->is_referenced_by_inline_ = true; }

  // Swap with another function.  Used only for the thunk which calls
  // recover.
  void
  swap_for_recover(Function *);

  // Traverse the tree.
  int
  traverse(Traverse*);

  // Determine types in the function.
  void
  determine_types();

  // Return an expression for the function descriptor, given the named
  // object for this function.  This may only be called for functions
  // without a closure.  This will be an immutable struct with one
  // field that points to the function's code.
  Expression*
  descriptor(Gogo*, Named_object*);

  // Set the descriptor for this function.  This is used when a
  // function declaration is followed by a function definition.
  void
  set_descriptor(Expression* descriptor)
  {
    go_assert(this->descriptor_ == NULL);
    this->descriptor_ = descriptor;
  }

  // Return the backend representation.
  Bfunction*
  get_or_make_decl(Gogo*, Named_object*);

  // Return the function's decl after it has been built.
  Bfunction*
  get_decl() const;

  // Set the function decl to hold a backend representation of the function
  // code.
  void
  build(Gogo*, Named_object*);

  // Get the statement that assigns values to this function's result struct.
  Bstatement*
  return_value(Gogo*, Named_object*, Location) const;

  // Get an expression for the variable holding the defer stack.
  Expression*
  defer_stack(Location);

  // Export the function.
  void
  export_func(Export*, const Named_object*) const;

  // Export a function with a type.
  static void
  export_func_with_type(Export*, const Named_object*,
			const Function_type*, Results*, bool nointerface,
			const std::string& asm_name, Block* block, Location);

  // Import a function.  Reports whether the import succeeded.
  static bool
  import_func(Import*, std::string* pname, Package** pkg,
	      bool* is_exported, Typed_identifier** receiver,
	      Typed_identifier_list** pparameters,
	      Typed_identifier_list** presults, bool* is_varargs,
	      bool* nointerface, std::string* asm_name, std::string* body);

 private:
  // Type for mapping from label names to Label objects.
  typedef Unordered_map(std::string, Label*) Labels;

  void
  build_defer_wrapper(Gogo*, Named_object*, Bstatement**, Bstatement**);

  typedef std::vector<std::pair<Named_object*,
				Location> > Closure_fields;

  // The function's type.
  Function_type* type_;
  // The enclosing function.  This is NULL when there isn't one, which
  // is the normal case.
  Named_object* enclosing_;
  // The result variables, if any.
  Results* results_;
  // If there is a closure, this is the list of variables which appear
  // in the closure.  This is created by the parser, and then resolved
  // to a real type when we lower parse trees.
  Closure_fields closure_fields_;
  // The closure variable, passed as a parameter using the static
  // chain parameter.  Normally NULL.
  Named_object* closure_var_;
  // The outer block of statements in the function.
  Block* block_;
  // The source location of the start of the function.
  Location location_;
  // Labels defined or referenced in the function.
  Labels labels_;
  // The number of local types defined in this function.
  unsigned int local_type_count_;
  // The assembler name: this is the name that will be put in the object file.
  // Set by the go:linkname compiler directive.  This is normally empty.
  std::string asm_name_;
  // The function descriptor, if any.
  Expression* descriptor_;
  // The function decl.
  Bfunction* fndecl_;
  // The defer stack variable.  A pointer to this variable is used to
  // distinguish the defer stack for one function from another.  This
  // is NULL unless we actually need a defer stack.
  Temporary_statement* defer_stack_;
  // Pragmas for this function.  This is a set of GOPRAGMA bits.
  unsigned int pragmas_;
  // Number of nested functions defined within this function.
  unsigned int nested_functions_;
  // True if this function is sink-named.  No code is generated.
  bool is_sink_ : 1;
  // True if the result variables are named.
  bool results_are_named_ : 1;
  // True if this function is a stub method created for an unnamed
  // type.
  bool is_unnamed_type_stub_method_ : 1;
  // True if this function calls the predeclared recover function.
  bool calls_recover_ : 1;
  // True if this a thunk built for a function which calls recover.
  bool is_recover_thunk_ : 1;
  // True if this function already has a recover thunk.
  bool has_recover_thunk_ : 1;
  // True if this is a thunk built for a defer statement that calls
  // the __go_set_defer_retaddr runtime function.
  bool calls_defer_retaddr_ : 1;
  // True if this is a function built by the compiler to as a hash or
  // equality function for some type.
  bool is_type_specific_function_ : 1;
  // True if this function should be put in a unique section.  This is
  // turned on for field tracking.
  bool in_unique_section_ : 1;
  // True if we should export the body of this function for
  // cross-package inlining.
  bool export_for_inlining_ : 1;
  // True if this function is inline only: if it should not be emitted
  // if it is not inlined.
  bool is_inline_only_ : 1;
  // True if this function is referenced from an inlined body that
  // will be put into the export data.
  bool is_referenced_by_inline_ : 1;
  // True if we should make this function visible to other packages
  // because of a go:linkname directive.
  bool is_exported_by_linkname_ : 1;
};

// A snapshot of the current binding state.

class Bindings_snapshot
{
 public:
  Bindings_snapshot(const Block*, Location);

  // Report any errors appropriate for a goto from the current binding
  // state of B to this one.
  void
  check_goto_from(const Block* b, Location);

  // Report any errors appropriate for a goto from this binding state
  // to the current state of B.
  void
  check_goto_to(const Block* b);

 private:
  bool
  check_goto_block(Location, const Block*, const Block*, size_t*);

  void
  check_goto_defs(Location, const Block*, size_t, size_t);

  // The current block.
  const Block* block_;
  // The number of names currently defined in each open block.
  // Element 0 is this->block_, element 1 is
  // this->block_->enclosing(), etc.
  std::vector<size_t> counts_;
  // The location where this snapshot was taken.
  Location location_;
};

// A function declaration.

class Function_declaration
{
 public:
  Function_declaration(Function_type* fntype, Location location)
    : fntype_(fntype), location_(location), asm_name_(), descriptor_(NULL),
      fndecl_(NULL), pragmas_(0), imported_body_(),
      is_on_inlinable_list_(false)
  { }

  Function_type*
  type() const
  { return this->fntype_; }

  Location
  location() const
  { return this->location_; }

  // Return whether this function declaration is a method.
  bool
  is_method() const;

  const std::string&
  asm_name() const
  { return this->asm_name_; }

  // Set the assembler name.
  void
  set_asm_name(const std::string& asm_name)
  { this->asm_name_ = asm_name; }

  // Return the pragmas for this function.
  unsigned int
  pragmas() const
  { return this->pragmas_; }

  // Set the pragmas for this function.
  void
  set_pragmas(unsigned int pragmas)
  {
    this->pragmas_ = pragmas;
  }

  // Whether this method should not be included in the type
  // descriptor.
  bool
  nointerface() const;

  // Record that this method should not be included in the type
  // descriptor.
  void
  set_nointerface();

  // Whether we have an imported function body.
  bool
  has_imported_body() const
  { return !this->imported_body_.empty(); }

  // Record the imported body of this function.
  void
  set_imported_body(Import* imp, const std::string& imported_body)
  {
    this->imp_ = imp;
    this->imported_body_ = imported_body;
  }

  // Whether this declaration is on the list of inlinable functions.
  bool
  is_on_inlinable_list() const
  { return this->is_on_inlinable_list_; }

  // Set that this function is on the list of inlinable functions.
  void
  set_is_on_inlinable_list()
  { this->is_on_inlinable_list_ = true; }

  // Import the function body, creating a function.
  void
  import_function_body(Gogo*, Named_object*);

  // Return an expression for the function descriptor, given the named
  // object for this function.  This may only be called for functions
  // without a closure.  This will be an immutable struct with one
  // field that points to the function's code.
  Expression*
  descriptor(Gogo*, Named_object*);

  // Return true if we have created a descriptor for this declaration.
  bool
  has_descriptor() const
  { return this->descriptor_ != NULL; }

  // Return a backend representation.
  Bfunction*
  get_or_make_decl(Gogo*, Named_object*);

  // If there is a descriptor, build it into the backend
  // representation.
  void
  build_backend_descriptor(Gogo*);

  // Export a function declaration.
  void
  export_func(Export* exp, const Named_object* no) const
  {
    Function::export_func_with_type(exp, no, this->fntype_, NULL,
				    this->is_method() && this->nointerface(),
				    this->asm_name_, NULL, this->location_);
  }

  // Check that the types used in this declaration's signature are defined.
  void
  check_types() const;

 private:
  // The type of the function.
  Function_type* fntype_;
  // The location of the declaration.
  Location location_;
  // The assembler name: this is the name to use in references to the
  // function.  This is normally empty.
  std::string asm_name_;
  // The function descriptor, if any.
  Expression* descriptor_;
  // The function decl if needed.
  Bfunction* fndecl_;
  // Pragmas for this function.  This is a set of GOPRAGMA bits.
  unsigned int pragmas_;
  // Importer for function body if imported from a different package.
  Import* imp_;
  // Export data for function body if imported from a different package.
  std::string imported_body_;
  // Whether this declaration is already on the list of inlinable functions.
  bool is_on_inlinable_list_;
};

// A variable.

class Variable
{
 public:
  Variable(Type*, Expression*, bool is_global, bool is_parameter,
	   bool is_receiver, Location);

  // Get the type of the variable.
  Type*
  type();

  Type*
  type() const;

  // Return whether the type is defined yet.
  bool
  has_type() const;

  // Get the initial value.
  Expression*
  init() const
  { return this->init_; }

  // Return whether there are any preinit statements.
  bool
  has_pre_init() const
  { return this->preinit_ != NULL; }

  // Return the preinit statements if any.
  Block*
  preinit() const
  { return this->preinit_; }

  // Return whether this is a global variable.
  bool
  is_global() const
  { return this->is_global_; }

  // Return whether this is a function parameter.
  bool
  is_parameter() const
  { return this->is_parameter_; }

  // Return whether this is a closure (static chain) parameter.
  bool
  is_closure() const
  { return this->is_closure_; }

  // Change this parameter to be a closure.
  void
  set_is_closure()
  {
    this->is_closure_ = true;
  }

  // Return whether this is the receiver parameter of a method.
  bool
  is_receiver() const
  { return this->is_receiver_; }

  // Change this parameter to be a receiver.  This is used when
  // creating the thunks created for functions which call recover.
  void
  set_is_receiver()
  {
    go_assert(this->is_parameter_);
    this->is_receiver_ = true;
  }

  // Change this parameter to not be a receiver.  This is used when
  // creating the thunks created for functions which call recover.
  void
  set_is_not_receiver()
  {
    go_assert(this->is_parameter_);
    this->is_receiver_ = false;
  }

  // Return whether this is the varargs parameter of a function.
  bool
  is_varargs_parameter() const
  { return this->is_varargs_parameter_; }

  // Whether this variable's address is taken.
  bool
  is_address_taken() const
  { return this->is_address_taken_; }

  // Whether this variable should live in the heap.
  bool
  is_in_heap() const
  { return this->is_address_taken_ && !this->is_global_; }

  // Note that something takes the address of this variable.
  void
  set_address_taken()
  { this->is_address_taken_ = true; }

  // Return whether the address is taken but does not escape.
  bool
  is_non_escaping_address_taken() const
  { return this->is_non_escaping_address_taken_; }

  // Note that something takes the address of this variable such that
  // the address does not escape the function.
  void
  set_non_escaping_address_taken()
  { this->is_non_escaping_address_taken_ = true; }

  // Get the source location of the variable's declaration.
  Location
  location() const
  { return this->location_; }

  // Record that this is the varargs parameter of a function.
  void
  set_is_varargs_parameter()
  {
    go_assert(this->is_parameter_);
    this->is_varargs_parameter_ = true;
  }

  // Return whether the variable has been used.
  bool
  is_used() const
  { return this->is_used_; }

  // Mark that the variable has been used.
  void
  set_is_used()
  { this->is_used_ = true; }

  // Clear the initial value; used for error handling and write barriers.
  void
  clear_init()
  { this->init_ = NULL; }

  // Set the initial value; used for converting shortcuts.
  void
  set_init(Expression* init)
  { this->init_ = init; }

  // Get the preinit block, a block of statements to be run before the
  // initialization expression.
  Block*
  preinit_block(Gogo*);

  // Add a statement to be run before the initialization expression.
  // This is only used for global variables.
  void
  add_preinit_statement(Gogo*, Statement*);

  // Lower the initialization expression after parsing is complete.
  void
  lower_init_expression(Gogo*, Named_object*, Statement_inserter*);

  // Flatten the initialization expression after ordering evaluations.
  void
  flatten_init_expression(Gogo*, Named_object*, Statement_inserter*);

  // A special case: the init value is used only to determine the
  // type.  This is used if the variable is defined using := with the
  // comma-ok form of a map index or a receive expression.  The init
  // value is actually the map index expression or receive expression.
  // We use this because we may not know the right type at parse time.
  void
  set_type_from_init_tuple()
  { this->type_from_init_tuple_ = true; }

  // Another special case: the init value is used only to determine
  // the type.  This is used if the variable is defined using := with
  // a range clause.  The init value is the range expression.  The
  // type of the variable is the index type of the range expression
  // (i.e., the first value returned by a range).
  void
  set_type_from_range_index()
  { this->type_from_range_index_ = true; }

  // Another special case: like set_type_from_range_index, but the
  // type is the value type of the range expression (i.e., the second
  // value returned by a range).
  void
  set_type_from_range_value()
  { this->type_from_range_value_ = true; }

  // Another special case: the init value is used only to determine
  // the type.  This is used if the variable is defined using := with
  // a case in a select statement.  The init value is the channel.
  // The type of the variable is the channel's element type.
  void
  set_type_from_chan_element()
  { this->type_from_chan_element_ = true; }

  // After we lower the select statement, we once again set the type
  // from the initialization expression.
  void
  clear_type_from_chan_element()
  {
    go_assert(this->type_from_chan_element_);
    this->type_from_chan_element_ = false;
  }

  // TRUE if this variable was created for a type switch clause.
  bool
  is_type_switch_var() const
  { return this->is_type_switch_var_; }

  // Note that this variable was created for a type switch clause.
  void
  set_is_type_switch_var()
  { this->is_type_switch_var_ = true; }

  // Mark the variable as going into a unique section.
  void
  set_in_unique_section()
  {
    go_assert(this->is_global_);
    this->in_unique_section_ = true;
  }

  // Mark the variable as referenced by an inline body.
  void
  set_is_referenced_by_inline()
  {
    go_assert(this->is_global_);
    this->is_referenced_by_inline_ = true;
  }

  // Return the top-level declaration for this variable.
  Statement*
  toplevel_decl()
  { return this->toplevel_decl_; }

  // Set the top-level declaration for this variable. Only used for local
  // variables
  void
  set_toplevel_decl(Statement* s)
  {
    go_assert(!this->is_global_ && !this->is_parameter_ && !this->is_receiver_);
    this->toplevel_decl_ = s;
  }

  // Traverse the initializer expression.
  int
  traverse_expression(Traverse*, unsigned int traverse_mask);

  // Determine the type of the variable if necessary.
  void
  determine_type();

  // Get the backend representation of the variable.
  Bvariable*
  get_backend_variable(Gogo*, Named_object*, const Package*,
		       const std::string&);

  // Get the initial value of the variable.  This may only
  // be called if has_pre_init() returns false.
  Bexpression*
  get_init(Gogo*, Named_object* function);

  // Return a series of statements which sets the value of the
  // variable in DECL.  This should only be called is has_pre_init()
  // returns true.  DECL may be NULL for a sink variable.
  Bstatement*
  get_init_block(Gogo*, Named_object* function, Bvariable* decl);

  // Export the variable.
  void
  export_var(Export*, const Named_object*) const;

  // Import a variable.  Reports whether the import succeeded.
  static bool
  import_var(Import*, std::string* pname, Package** pkg, bool* is_exported,
	     Type** ptype);

 private:
  // The type of a tuple.
  Type*
  type_from_tuple(Expression*, bool) const;

  // The type of a range.
  Type*
  type_from_range(Expression*, bool, bool) const;

  // The element type of a channel.
  Type*
  type_from_chan_element(Expression*, bool) const;

  // The variable's type.  This may be NULL if the type is set from
  // the expression.
  Type* type_;
  // The initial value.  This may be NULL if the variable should be
  // initialized to the default value for the type.
  Expression* init_;
  // Statements to run before the init statement.
  Block* preinit_;
  // Location of variable definition.
  Location location_;
  // Backend representation.
  Bvariable* backend_;
  // Whether this is a global variable.
  bool is_global_ : 1;
  // Whether this is a function parameter.
  bool is_parameter_ : 1;
  // Whether this is a closure parameter.
  bool is_closure_ : 1;
  // Whether this is the receiver parameter of a method.
  bool is_receiver_ : 1;
  // Whether this is the varargs parameter of a function.
  bool is_varargs_parameter_ : 1;
  // Whether this variable is ever referenced.
  bool is_used_ : 1;
  // Whether something takes the address of this variable.  For a
  // local variable this implies that the variable has to be on the
  // heap if it escapes from its function.
  bool is_address_taken_ : 1;
  // Whether something takes the address of this variable such that
  // the address does not escape the function.
  bool is_non_escaping_address_taken_ : 1;
  // True if we have seen this variable in a traversal.
  bool seen_ : 1;
  // True if we have lowered the initialization expression.
  bool init_is_lowered_ : 1;
  // True if we have flattened the initialization expression.
  bool init_is_flattened_ : 1;
  // True if init is a tuple used to set the type.
  bool type_from_init_tuple_ : 1;
  // True if init is a range clause and the type is the index type.
  bool type_from_range_index_ : 1;
  // True if init is a range clause and the type is the value type.
  bool type_from_range_value_ : 1;
  // True if init is a channel and the type is the channel's element type.
  bool type_from_chan_element_ : 1;
  // True if this is a variable created for a type switch case.
  bool is_type_switch_var_ : 1;
  // True if we have determined types.
  bool determined_type_ : 1;
  // True if this variable should be put in a unique section.  This is
  // used for field tracking.
  bool in_unique_section_ : 1;
  // True if this variable is referenced from an inlined body that
  // will be put into the export data.
  bool is_referenced_by_inline_ : 1;
  // The top-level declaration for this variable. Only used for local
  // variables. Must be a Temporary_statement if not NULL.
  Statement* toplevel_decl_;
};

// A variable which is really the name for a function return value, or
// part of one.

class Result_variable
{
 public:
  Result_variable(Type* type, Function* function, int index,
		  Location location)
    : type_(type), function_(function), index_(index), location_(location),
      backend_(NULL), is_address_taken_(false),
      is_non_escaping_address_taken_(false)
  { }

  // Get the type of the result variable.
  Type*
  type() const
  { return this->type_; }

  // Get the function that this is associated with.
  Function*
  function() const
  { return this->function_; }

  // Index in the list of function results.
  int
  index() const
  { return this->index_; }

  // The location of the variable definition.
  Location
  location() const
  { return this->location_; }

  // Whether this variable's address is taken.
  bool
  is_address_taken() const
  { return this->is_address_taken_; }

  // Note that something takes the address of this variable.
  void
  set_address_taken()
  { this->is_address_taken_ = true; }

  // Return whether the address is taken but does not escape.
  bool
  is_non_escaping_address_taken() const
  { return this->is_non_escaping_address_taken_; }

  // Note that something takes the address of this variable such that
  // the address does not escape the function.
  void
  set_non_escaping_address_taken()
  { this->is_non_escaping_address_taken_ = true; }

  // Whether this variable should live in the heap.
  bool
  is_in_heap() const
  { return this->is_address_taken_; }

  // Set the function.  This is used when cloning functions which call
  // recover.
  void
  set_function(Function* function)
  { this->function_ = function; }

  // Get the backend representation of the variable.
  Bvariable*
  get_backend_variable(Gogo*, Named_object*, const std::string&);

 private:
  // Type of result variable.
  Type* type_;
  // Function with which this is associated.
  Function* function_;
  // Index in list of results.
  int index_;
  // Where the result variable is defined.
  Location location_;
  // Backend representation.
  Bvariable* backend_;
  // Whether something takes the address of this variable.
  bool is_address_taken_;
  // Whether something takes the address of this variable such that
  // the address does not escape the function.
  bool is_non_escaping_address_taken_;
};

// The value we keep for a named constant.  This lets us hold a type
// and an expression.

class Named_constant
{
 public:
  Named_constant(Type* type, Expression* expr, int iota_value,
		 Location location)
    : type_(type), expr_(expr), iota_value_(iota_value), location_(location),
      lowering_(false), is_sink_(false), bconst_(NULL)
  { }

  Type*
  type() const
  { return this->type_; }

  void
  set_type(Type* t);

  Expression*
  expr() const
  { return this->expr_; }

  int
  iota_value() const
  { return this->iota_value_; }

  Location
  location() const
  { return this->location_; }

  // Whether we are lowering.
  bool
  lowering() const
  { return this->lowering_; }

  // Set that we are lowering.
  void
  set_lowering()
  { this->lowering_ = true; }

  // We are no longer lowering.
  void
  clear_lowering()
  { this->lowering_ = false; }

  bool
  is_sink() const
  { return this->is_sink_; }

  void
  set_is_sink()
  { this->is_sink_ = true; }

  // Traverse the expression.
  int
  traverse_expression(Traverse*);

  // Determine the type of the constant if necessary.
  void
  determine_type();

  // Indicate that we found and reported an error for this constant.
  void
  set_error();

  // Export the constant.
  void
  export_const(Export*, const std::string& name) const;

  // Import a constant.
  static void
  import_const(Import*, std::string*, Type**, Expression**);

  // Get the backend representation of the constant value.
  Bexpression*
  get_backend(Gogo*, Named_object*);

 private:
  // The type of the constant.
  Type* type_;
  // The expression for the constant.
  Expression* expr_;
  // If the predeclared constant iota is used in EXPR_, this is the
  // value it will have.  We do this because at parse time we don't
  // know whether the name "iota" will refer to the predeclared
  // constant or to something else.  We put in the right value in when
  // we lower.
  int iota_value_;
  // The location of the definition.
  Location location_;
  // Whether we are currently lowering this constant.
  bool lowering_;
  // Whether this constant is blank named and needs only type checking.
  bool is_sink_;
  // The backend representation of the constant value.
  Bexpression* bconst_;
};

// A type declaration.

class Type_declaration
{
 public:
  Type_declaration(Location location)
    : location_(location), in_function_(NULL), in_function_index_(0),
      methods_(), issued_warning_(false)
  { }

  // Return the location.
  Location
  location() const
  { return this->location_; }

  // Return the function in which this type is declared.  This will
  // return NULL for a type declared in global scope.
  Named_object*
  in_function(unsigned int* pindex)
  {
    *pindex = this->in_function_index_;
    return this->in_function_;
  }

  // Set the function in which this type is declared.
  void
  set_in_function(Named_object* f, unsigned int index)
  {
    this->in_function_ = f;
    this->in_function_index_ = index;
  }

  // Add a method to this type.  This is used when methods are defined
  // before the type.
  Named_object*
  add_method(const std::string& name, Function* function);

  // Add a method declaration to this type.
  Named_object*
  add_method_declaration(const std::string& name, Package*,
			 Function_type* type, Location location);

  // Add an already created object as a method.
  void
  add_existing_method(Named_object* no)
  { this->methods_.push_back(no); }

  // Return whether any methods were defined.
  bool
  has_methods() const;

  // Return the methods.
  const std::vector<Named_object*>*
  methods() const
  { return &this->methods_; }

  // Define methods when the real type is known.
  void
  define_methods(Named_type*);

  // This is called if we are trying to use this type.  It returns
  // true if we should issue a warning.
  bool
  using_type();

 private:
  // The location of the type declaration.
  Location location_;
  // If this type is declared in a function, a pointer back to the
  // function in which it is defined.
  Named_object* in_function_;
  // The index of this type in IN_FUNCTION_.
  unsigned int in_function_index_;
  // Methods defined before the type is defined.
  std::vector<Named_object*> methods_;
  // True if we have issued a warning about a use of this type
  // declaration when it is undefined.
  bool issued_warning_;
};

// An unknown object.  These are created by the parser for forward
// references to names which have not been seen before.  In a correct
// program, these will always point to a real definition by the end of
// the parse.  Because they point to another Named_object, these may
// only be referenced by Unknown_expression objects.

class Unknown_name
{
 public:
  Unknown_name(Location location)
    : location_(location), real_named_object_(NULL)
  { }

  // Return the location where this name was first seen.
  Location
  location() const
  { return this->location_; }

  // Return the real named object that this points to, or NULL if it
  // was never resolved.
  Named_object*
  real_named_object() const
  { return this->real_named_object_; }

  // Set the real named object that this points to.
  void
  set_real_named_object(Named_object* no);

 private:
  // The location where this name was first seen.
  Location location_;
  // The real named object when it is known.
  Named_object*
  real_named_object_;
};

// A named object named.  This is the result of a declaration.  We
// don't use a superclass because they all have to be handled
// differently.

class Named_object
{
 public:
  enum Classification
  {
    // An uninitialized Named_object.  We should never see this.
    NAMED_OBJECT_UNINITIALIZED,
    // An erroneous name.  This indicates a parse error, to avoid
    // later errors about undefined references.
    NAMED_OBJECT_ERRONEOUS,
    // An unknown name.  This is used for forward references.  In a
    // correct program, these will all be resolved by the end of the
    // parse.
    NAMED_OBJECT_UNKNOWN,
    // A const.
    NAMED_OBJECT_CONST,
    // A type.
    NAMED_OBJECT_TYPE,
    // A forward type declaration.
    NAMED_OBJECT_TYPE_DECLARATION,
    // A var.
    NAMED_OBJECT_VAR,
    // A result variable in a function.
    NAMED_OBJECT_RESULT_VAR,
    // The blank identifier--the special variable named _.
    NAMED_OBJECT_SINK,
    // A func.
    NAMED_OBJECT_FUNC,
    // A forward func declaration.
    NAMED_OBJECT_FUNC_DECLARATION,
    // A package.
    NAMED_OBJECT_PACKAGE
  };

  // Return the classification.
  Classification
  classification() const
  { return this->classification_; }

  // Classifiers.

  bool
  is_erroneous() const
  { return this->classification_ == NAMED_OBJECT_ERRONEOUS; }

  bool
  is_unknown() const
  { return this->classification_ == NAMED_OBJECT_UNKNOWN; }

  bool
  is_const() const
  { return this->classification_ == NAMED_OBJECT_CONST; }

  bool
  is_type() const
  { return this->classification_ == NAMED_OBJECT_TYPE; }

  bool
  is_type_declaration() const
  { return this->classification_ == NAMED_OBJECT_TYPE_DECLARATION; }

  bool
  is_variable() const
  { return this->classification_ == NAMED_OBJECT_VAR; }

  bool
  is_result_variable() const
  { return this->classification_ == NAMED_OBJECT_RESULT_VAR; }

  bool
  is_sink() const
  { return this->classification_ == NAMED_OBJECT_SINK; }

  bool
  is_function() const
  { return this->classification_ == NAMED_OBJECT_FUNC; }

  bool
  is_function_declaration() const
  { return this->classification_ == NAMED_OBJECT_FUNC_DECLARATION; }

  bool
  is_package() const
  { return this->classification_ == NAMED_OBJECT_PACKAGE; }

  // Creators.

  static Named_object*
  make_erroneous_name(const std::string& name)
  { return new Named_object(name, NULL, NAMED_OBJECT_ERRONEOUS); }

  static Named_object*
  make_unknown_name(const std::string& name, Location);

  static Named_object*
  make_constant(const Typed_identifier&, const Package*, Expression*,
		int iota_value);

  static Named_object*
  make_type(const std::string&, const Package*, Type*, Location);

  static Named_object*
  make_type_declaration(const std::string&, const Package*, Location);

  static Named_object*
  make_variable(const std::string&, const Package*, Variable*);

  static Named_object*
  make_result_variable(const std::string&, Result_variable*);

  static Named_object*
  make_sink();

  static Named_object*
  make_function(const std::string&, const Package*, Function*);

  static Named_object*
  make_function_declaration(const std::string&, const Package*, Function_type*,
			    Location);

  static Named_object*
  make_package(const std::string& alias, Package* package);

  // Getters.

  Unknown_name*
  unknown_value()
  {
    go_assert(this->classification_ == NAMED_OBJECT_UNKNOWN);
    return this->u_.unknown_value;
  }

  const Unknown_name*
  unknown_value() const
  {
    go_assert(this->classification_ == NAMED_OBJECT_UNKNOWN);
    return this->u_.unknown_value;
  }

  Named_constant*
  const_value()
  {
    go_assert(this->classification_ == NAMED_OBJECT_CONST);
    return this->u_.const_value;
  }

  const Named_constant*
  const_value() const
  {
    go_assert(this->classification_ == NAMED_OBJECT_CONST);
    return this->u_.const_value;
  }

  Named_type*
  type_value()
  {
    go_assert(this->classification_ == NAMED_OBJECT_TYPE);
    return this->u_.type_value;
  }

  const Named_type*
  type_value() const
  {
    go_assert(this->classification_ == NAMED_OBJECT_TYPE);
    return this->u_.type_value;
  }

  Type_declaration*
  type_declaration_value()
  {
    go_assert(this->classification_ == NAMED_OBJECT_TYPE_DECLARATION);
    return this->u_.type_declaration;
  }

  const Type_declaration*
  type_declaration_value() const
  {
    go_assert(this->classification_ == NAMED_OBJECT_TYPE_DECLARATION);
    return this->u_.type_declaration;
  }

  Variable*
  var_value()
  {
    go_assert(this->classification_ == NAMED_OBJECT_VAR);
    return this->u_.var_value;
  }

  const Variable*
  var_value() const
  {
    go_assert(this->classification_ == NAMED_OBJECT_VAR);
    return this->u_.var_value;
  }

  Result_variable*
  result_var_value()
  {
    go_assert(this->classification_ == NAMED_OBJECT_RESULT_VAR);
    return this->u_.result_var_value;
  }

  const Result_variable*
  result_var_value() const
  {
    go_assert(this->classification_ == NAMED_OBJECT_RESULT_VAR);
    return this->u_.result_var_value;
  }

  Function*
  func_value()
  {
    go_assert(this->classification_ == NAMED_OBJECT_FUNC);
    return this->u_.func_value;
  }

  const Function*
  func_value() const
  {
    go_assert(this->classification_ == NAMED_OBJECT_FUNC);
    return this->u_.func_value;
  }

  Function_declaration*
  func_declaration_value()
  {
    go_assert(this->classification_ == NAMED_OBJECT_FUNC_DECLARATION);
    return this->u_.func_declaration_value;
  }

  const Function_declaration*
  func_declaration_value() const
  {
    go_assert(this->classification_ == NAMED_OBJECT_FUNC_DECLARATION);
    return this->u_.func_declaration_value;
  }

  Package*
  package_value()
  {
    go_assert(this->classification_ == NAMED_OBJECT_PACKAGE);
    return this->u_.package_value;
  }

  const Package*
  package_value() const
  {
    go_assert(this->classification_ == NAMED_OBJECT_PACKAGE);
    return this->u_.package_value;
  }

  const std::string&
  name() const
  { return this->name_; }

  // Return the name to use in an error message.  The difference is
  // that if this Named_object is defined in a different package, this
  // will return PACKAGE.NAME.
  std::string
  message_name() const;

  const Package*
  package() const
  { return this->package_; }

  // Resolve an unknown value if possible.  This returns the same
  // Named_object or a new one.
  Named_object*
  resolve()
  {
    Named_object* ret = this;
    if (this->is_unknown())
      {
	Named_object* r = this->unknown_value()->real_named_object();
	if (r != NULL)
	  ret = r;
      }
    return ret;
  }

  const Named_object*
  resolve() const
  {
    const Named_object* ret = this;
    if (this->is_unknown())
      {
	const Named_object* r = this->unknown_value()->real_named_object();
	if (r != NULL)
	  ret = r;
      }
    return ret;
  }

  // The location where this object was defined or referenced.
  Location
  location() const;

  // Convert a variable to the backend representation.
  Bvariable*
  get_backend_variable(Gogo*, Named_object* function);

  // Return the external identifier for this object.
  std::string
  get_id(Gogo*);

  // Get the backend representation of this object.
  void
  get_backend(Gogo*, std::vector<Bexpression*>&, std::vector<Btype*>&,
              std::vector<Bfunction*>&);

  // Define a type declaration.
  void
  set_type_value(Named_type*);

  // Define a function declaration.
  void
  set_function_value(Function*);

  // Declare an unknown name as a type declaration.
  void
  declare_as_type();

  // Export this object.
  void
  export_named_object(Export*) const;

  // Mark this named object as an invalid redefinition of another object.
  void
  set_is_redefinition()
  { this->is_redefinition_ = true; }

  // Return whether or not this object is a invalid redefinition of another
  // object.
  bool
  is_redefinition() const
  { return this->is_redefinition_; }

 private:
  Named_object(const std::string&, const Package*, Classification);

  // The name of the object.
  std::string name_;
  // The package that this object is in.  This is NULL if it is in the
  // file we are compiling.
  const Package* package_;
  // The type of object this is.
  Classification classification_;
  // The real data.
  union
  {
    Unknown_name* unknown_value;
    Named_constant* const_value;
    Named_type* type_value;
    Type_declaration* type_declaration;
    Variable* var_value;
    Result_variable* result_var_value;
    Function* func_value;
    Function_declaration* func_declaration_value;
    Package* package_value;
  } u_;
  // True if this object is an invalid redefinition of another object.
  bool is_redefinition_;
};

// A binding contour.  This binds names to objects.

class Bindings
{
 public:
  // Type for mapping from names to objects.
  typedef Unordered_map(std::string, Named_object*) Contour;

  Bindings(Bindings* enclosing);

  // Add an erroneous name.
  Named_object*
  add_erroneous_name(const std::string& name)
  { return this->add_named_object(Named_object::make_erroneous_name(name)); }

  // Add an unknown name.
  Named_object*
  add_unknown_name(const std::string& name, Location location)
  {
    return this->add_named_object(Named_object::make_unknown_name(name,
								  location));
  }

  // Add a constant.
  Named_object*
  add_constant(const Typed_identifier& tid, const Package* package,
	       Expression* expr, int iota_value)
  {
    return this->add_named_object(Named_object::make_constant(tid, package,
							      expr,
							      iota_value));
  }

  // Add a type.
  Named_object*
  add_type(const std::string& name, const Package* package, Type* type,
	   Location location)
  {
    return this->add_named_object(Named_object::make_type(name, package, type,
							  location));
  }

  // Add a named type.  This is used for builtin types, and to add an
  // imported type to the global scope.
  Named_object*
  add_named_type(Named_type* named_type);

  // Add a type declaration.
  Named_object*
  add_type_declaration(const std::string& name, const Package* package,
		       Location location)
  {
    Named_object* no = Named_object::make_type_declaration(name, package,
							   location);
    return this->add_named_object(no);
  }

  // Add a variable.
  Named_object*
  add_variable(const std::string& name, const Package* package,
	       Variable* variable)
  {
    return this->add_named_object(Named_object::make_variable(name, package,
							      variable));
  }

  // Add a result variable.
  Named_object*
  add_result_variable(const std::string& name, Result_variable* result)
  {
    return this->add_named_object(Named_object::make_result_variable(name,
								     result));
  }

  // Add a function.
  Named_object*
  add_function(const std::string& name, const Package*, Function* function);

  // Add a function declaration.
  Named_object*
  add_function_declaration(const std::string& name, const Package* package,
			   Function_type* type, Location location);

  // Add a package.  The location is the location of the import
  // statement.
  Named_object*
  add_package(const std::string& alias, Package* package)
  {
    Named_object* no = Named_object::make_package(alias, package);
    return this->add_named_object(no);
  }

  // Define a type which was already declared.
  void
  define_type(Named_object*, Named_type*);

  // Add a method to the list of objects.  This is not added to the
  // lookup table.
  void
  add_method(Named_object*);

  // Add a named object to this binding.
  Named_object*
  add_named_object(Named_object* no)
  { return this->add_named_object_to_contour(&this->bindings_, no); }

  // Clear all names in file scope from the bindings.
  void
  clear_file_scope(Gogo*);

  // Look up a name in this binding contour and in any enclosing
  // binding contours.  This returns NULL if the name is not found.
  Named_object*
  lookup(const std::string&) const;

  // Look up a name in this binding contour without looking in any
  // enclosing binding contours.  Returns NULL if the name is not found.
  Named_object*
  lookup_local(const std::string&) const;

  // Remove a name.
  void
  remove_binding(Named_object*);

  // Mark all variables as used.  This is used for some types of parse
  // error.
  void
  mark_locals_used();

  // Traverse the tree.  See the Traverse class.
  int
  traverse(Traverse*, bool is_global);

  // Iterate over definitions.  This does not include things which
  // were only declared.

  typedef std::vector<Named_object*>::const_iterator
    const_definitions_iterator;

  const_definitions_iterator
  begin_definitions() const
  { return this->named_objects_.begin(); }

  const_definitions_iterator
  end_definitions() const
  { return this->named_objects_.end(); }

  // Return the number of definitions.
  size_t
  size_definitions() const
  { return this->named_objects_.size(); }

  // Return whether there are no definitions.
  bool
  empty_definitions() const
  { return this->named_objects_.empty(); }

  // Iterate over declarations.  This is everything that has been
  // declared, which includes everything which has been defined.

  typedef Contour::const_iterator const_declarations_iterator;

  const_declarations_iterator
  begin_declarations() const
  { return this->bindings_.begin(); }

  const_declarations_iterator
  end_declarations() const
  { return this->bindings_.end(); }

  // Return the number of declarations.
  size_t
  size_declarations() const
  { return this->bindings_.size(); }

  // Return whether there are no declarations.
  bool
  empty_declarations() const
  { return this->bindings_.empty(); }

  // Return the first declaration.
  Named_object*
  first_declaration()
  { return this->bindings_.empty() ? NULL : this->bindings_.begin()->second; }

  // Dump to stderr for debugging
  void debug_dump();

 private:
  Named_object*
  add_named_object_to_contour(Contour*, Named_object*);

  Named_object*
  new_definition(Named_object*, Named_object*);

  // Enclosing bindings.
  Bindings* enclosing_;
  // The list of objects.
  std::vector<Named_object*> named_objects_;
  // The mapping from names to objects.
  Contour bindings_;
};

// A label.

class Label
{
 public:
  Label(const std::string& name)
    : name_(name), location_(Linemap::unknown_location()), snapshot_(NULL),
      refs_(), is_used_(false), blabel_(NULL), depth_(DEPTH_UNKNOWN)
  { }

  // Return the label's name.
  const std::string&
  name() const
  { return this->name_; }

  // Return whether the label has been defined.
  bool
  is_defined() const
  { return !Linemap::is_unknown_location(this->location_); }

  // Return whether the label has been used.
  bool
  is_used() const
  { return this->is_used_; }

  // Record that the label is used.
  void
  set_is_used()
  { this->is_used_ = true; }

  // Return whether this label is looping.
  bool
  looping() const
  { return this->depth_ == DEPTH_LOOPING; }

  // Set this label as looping.
  void
  set_looping()
  { this->depth_ = DEPTH_LOOPING; }

  // Return whether this label is nonlooping.
  bool
  nonlooping() const
  { return this->depth_ == DEPTH_NONLOOPING; }

  // Set this label as nonlooping.
  void
  set_nonlooping()
  { this->depth_ = DEPTH_NONLOOPING; }

  // Return the location of the definition.
  Location
  location() const
  { return this->location_; }

  // Return the bindings snapshot.
  Bindings_snapshot*
  snapshot() const
  { return this->snapshot_; }

  // Add a snapshot of a goto which refers to this label.
  void
  add_snapshot_ref(Bindings_snapshot* snapshot)
  {
    go_assert(Linemap::is_unknown_location(this->location_));
    this->refs_.push_back(snapshot);
  }

  // Return the list of snapshots of goto statements which refer to
  // this label.
  const std::vector<Bindings_snapshot*>&
  refs() const
  { return this->refs_; }

  // Clear the references.
  void
  clear_refs();

  // Define the label at LOCATION with the given bindings snapshot.
  void
  define(Location location, Bindings_snapshot* snapshot)
  {
    if (this->is_dummy_label())
      return;
    go_assert(Linemap::is_unknown_location(this->location_)
              && this->snapshot_ == NULL);
    this->location_ = location;
    this->snapshot_ = snapshot;
  }

  // Return the backend representation for this label.
  Blabel*
  get_backend_label(Translate_context*);

  // Return an expression for the address of this label.  This is used
  // to get the return address of a deferred function to see whether
  // the function may call recover.
  Bexpression*
  get_addr(Translate_context*, Location location);

  // Return a dummy label, representing any instance of the blank label.
  static Label*
  create_dummy_label();

  // Return TRUE if this is a dummy label.
  bool
  is_dummy_label() const
  { return this->name_ == "_"; }

  // A classification of a label's looping depth.
  enum Loop_depth
  {
    DEPTH_UNKNOWN,
    // A label never jumped to.
    DEPTH_NONLOOPING,
    // A label jumped to.
    DEPTH_LOOPING
  };

 private:
  // The name of the label.
  std::string name_;
  // The location of the definition.  This is 0 if the label has not
  // yet been defined.
  Location location_;
  // A snapshot of the set of bindings defined at this label, used to
  // issue errors about invalid goto statements.
  Bindings_snapshot* snapshot_;
  // A list of snapshots of goto statements which refer to this label.
  std::vector<Bindings_snapshot*> refs_;
  // Whether the label has been used.
  bool is_used_;
  // The backend representation.
  Blabel* blabel_;
  // The looping depth of this label, for escape analysis.
  Loop_depth depth_;
};

// An unnamed label.  These are used when lowering loops.

class Unnamed_label
{
 public:
  Unnamed_label(Location location)
    : location_(location), derived_from_(NULL), blabel_(NULL)
  { }

  // Get the location where the label is defined.
  Location
  location() const
  { return this->location_; }

  // Set the location where the label is defined.
  void
  set_location(Location location)
  { this->location_ = location; }

  // Get the top level statement this unnamed label is derived from.
  Statement*
  derived_from() const
  { return this->derived_from_; }

  // Set the top level statement this unnamed label is derived from.
  void
  set_derived_from(Statement* s)
  { this->derived_from_ = s; }

  // Return a statement which defines this label.
  Bstatement*
  get_definition(Translate_context*);

  // Return a goto to this label from LOCATION.
  Bstatement*
  get_goto(Translate_context*, Location location);

 private:
  // Return the backend representation.
  Blabel*
  get_blabel(Translate_context*);

  // The location where the label is defined.
  Location location_;
  // The top-level statement this unnamed label was derived/lowered from.
  // This is NULL is this label is not the top-level of a lowered statement.
  Statement* derived_from_;
  // The backend representation of this label.
  Blabel* blabel_;
};

// An alias for an imported package.

class Package_alias
{
 public:
  Package_alias(Location location)
      : location_(location), used_(0)
  { }

  // The location of the import statement.
  Location
  location()
  { return this->location_; }

  // How many symbols from the package were used under this alias.
  size_t
  used() const
  { return this->used_; }

  // Note that some symbol was used under this alias.
  void
  note_usage()
  { this->used_++; }

 private:
  // The location of the import statement.
  Location location_;
  // The amount of times some name from this package was used under this alias.
  size_t used_;
};

// An imported package.

class Package
{
 public:
  Package(const std::string& pkgpath, const std::string& pkgpath_symbol,
	  Location location);

  // Get the package path used for all symbols exported from this
  // package.
  const std::string&
  pkgpath() const
  { return this->pkgpath_; }

  // Return the package path to use for a symbol name.
  std::string
  pkgpath_symbol() const;

  // Set the package path symbol.
  void
  set_pkgpath_symbol(const std::string&);

  // Return the location of the most recent import statement.
  Location
  location() const
  { return this->location_; }

  // Return whether we know the name of this package yet.
  bool
  has_package_name() const
  { return !this->package_name_.empty(); }

  // The name that this package uses in its package clause.  This may
  // be different from the name in the associated Named_object if the
  // import statement used an alias.
  const std::string&
  package_name() const
  {
    go_assert(!this->package_name_.empty());
    return this->package_name_;
  }

  // Return the bindings.
  Bindings*
  bindings() const
  { return this->bindings_; }

  // Type used to map import names to package aliases.
  typedef std::map<std::string, Package_alias*> Aliases;

  // Return the set of package aliases.
  const Aliases&
  aliases() const
  { return this->aliases_; }

  // Note that some symbol from this package was used and qualified by ALIAS.
  // For dot imports, the ALIAS should be ".PACKAGE_NAME".
  void
  note_usage(const std::string& alias) const;

  // Note that USAGE might be a fake usage of this package.
  void
  note_fake_usage(Expression* usage) const
  { this->fake_uses_.insert(usage); }

  // Forget a given USAGE of this package.
  void
  forget_usage(Expression* usage) const;

  // Clear the used field for the next file.
  void
  clear_used();

  // Look up a name in the package.  Returns NULL if the name is not
  // found.
  Named_object*
  lookup(const std::string& name) const
  { return this->bindings_->lookup(name); }

  // Set the name of the package.
  void
  set_package_name(const std::string& name, Location);

  // Set the location of the package.  This is used to record the most
  // recent import location.
  void
  set_location(Location location)
  { this->location_ = location; }

  // Add a package name as an ALIAS for this package.
  Package_alias*
  add_alias(const std::string& alias, Location);

  // Add a constant to the package.
  Named_object*
  add_constant(const Typed_identifier& tid, Expression* expr)
  { return this->bindings_->add_constant(tid, this, expr, 0); }

  // Add a type to the package.
  Named_object*
  add_type(const std::string& name, Type* type, Location location)
  { return this->bindings_->add_type(name, this, type, location); }

  // Add a type declaration to the package.
  Named_object*
  add_type_declaration(const std::string& name, Location location)
  { return this->bindings_->add_type_declaration(name, this, location); }

  // Add a variable to the package.
  Named_object*
  add_variable(const std::string& name, Variable* variable)
  { return this->bindings_->add_variable(name, this, variable); }

  // Add a function declaration to the package.
  Named_object*
  add_function_declaration(const std::string& name, Function_type* type,
			   Location loc)
  { return this->bindings_->add_function_declaration(name, this, type, loc); }

  // Determine types of constants.
  void
  determine_types();

 private:
  // The package path for type reflection data.
  std::string pkgpath_;
  // The package path for symbol names.
  std::string pkgpath_symbol_;
  // The name that this package uses in the package clause.  This may
  // be the empty string if it is not yet known.
  std::string package_name_;
  // The names in this package.
  Bindings* bindings_;
  // The location of the most recent import statement.
  Location location_;
  // The set of aliases associated with this package.
  Aliases aliases_;
  // A set of possibly fake uses of this package. This is mutable because we
  // can track fake uses of a package even if we have a const pointer to it.
  mutable std::set<Expression*> fake_uses_;
};

// Return codes for the traversal functions.  This is not an enum
// because we want to be able to declare traversal functions in other
// header files without including this one.

// Continue traversal as usual.
const int TRAVERSE_CONTINUE = -1;

// Exit traversal.
const int TRAVERSE_EXIT = 0;

// Continue traversal, but skip components of the current object.
// E.g., if this is returned by Traverse::statement, we do not
// traverse the expressions in the statement even if
// traverse_expressions is set in the traverse_mask.
const int TRAVERSE_SKIP_COMPONENTS = 1;

// This class is used when traversing the parse tree.  The caller uses
// a subclass which overrides functions as desired.

class Traverse
{
 public:
  // These bitmasks say what to traverse.
  static const unsigned int traverse_variables =          0x1;
  static const unsigned int traverse_constants =          0x2;
  static const unsigned int traverse_functions =          0x4;
  static const unsigned int traverse_blocks =             0x8;
  static const unsigned int traverse_statements =        0x10;
  static const unsigned int traverse_expressions =       0x20;
  static const unsigned int traverse_types =             0x40;
  static const unsigned int traverse_func_declarations = 0x80;

  Traverse(unsigned int traverse_mask)
    : traverse_mask_(traverse_mask), types_seen_(NULL), expressions_seen_(NULL)
  { }

  virtual ~Traverse();

  // The bitmask of what to traverse.
  unsigned int
  traverse_mask() const
  { return this->traverse_mask_; }

  // Record that we are going to traverse a type.  This returns true
  // if the type has already been seen in this traversal.  This is
  // required because types, unlike expressions, can form a circular
  // graph.
  bool
  remember_type(const Type*);

  // Record that we are going to see an expression.  This returns true
  // if the expression has already been seen in this traversal.  This
  // is only needed for cases where multiple expressions can point to
  // a single one.
  bool
  remember_expression(const Expression*);

  // These functions return one of the TRAVERSE codes defined above.

  // If traverse_variables is set in the mask, this is called for
  // every variable in the tree.
  virtual int
  variable(Named_object*);

  // If traverse_constants is set in the mask, this is called for
  // every named constant in the tree.  The bool parameter is true for
  // a global constant.
  virtual int
  constant(Named_object*, bool);

  // If traverse_functions is set in the mask, this is called for
  // every function in the tree.
  virtual int
  function(Named_object*);

  // If traverse_blocks is set in the mask, this is called for every
  // block in the tree.
  virtual int
  block(Block*);

  // If traverse_statements is set in the mask, this is called for
  // every statement in the tree.
  virtual int
  statement(Block*, size_t* index, Statement*);

  // If traverse_expressions is set in the mask, this is called for
  // every expression in the tree.
  virtual int
  expression(Expression**);

  // If traverse_types is set in the mask, this is called for every
  // type in the tree.
  virtual int
  type(Type*);

  // If traverse_func_declarations is set in the mask, this is called
  // for every function declarations in the tree.
  virtual int
  function_declaration(Named_object*);

 private:
  // A hash table for types we have seen during this traversal.  Note
  // that this uses the default hash functions for pointers rather
  // than Type_hash_identical and Type_identical.  This is because for
  // traversal we care about seeing a specific type structure.  If
  // there are two separate instances of identical types, we want to
  // traverse both.
  typedef Unordered_set(const Type*) Types_seen;

  typedef Unordered_set(const Expression*) Expressions_seen;

  // Bitmask of what sort of objects to traverse.
  unsigned int traverse_mask_;
  // Types which have been seen in this traversal.
  Types_seen* types_seen_;
  // Expressions which have been seen in this traversal.
  Expressions_seen* expressions_seen_;
};

// This class looks for interface types to finalize methods of inherited
// interfaces.

class Finalize_methods : public Traverse
{
 public:
  Finalize_methods(Gogo* gogo)
    : Traverse(traverse_types),
      gogo_(gogo)
  { }

  int
  type(Type*);

 private:
  Gogo* gogo_;
};

// A class which makes it easier to insert new statements before the
// current statement during a traversal.

class Statement_inserter
{
 public:
  typedef Unordered_set(Statement*) Statements;

  // Empty constructor.
  Statement_inserter()
      : block_(NULL), pindex_(NULL), gogo_(NULL), var_(NULL),
        statements_added_(NULL)
  { }

  // Constructor for a statement in a block.
  Statement_inserter(Block* block, size_t *pindex, Statements *added = NULL)
      : block_(block), pindex_(pindex), gogo_(NULL), var_(NULL),
        statements_added_(added)
  { }

  // Constructor for a global variable.
  Statement_inserter(Gogo* gogo, Variable* var, Statements *added = NULL)
      : block_(NULL), pindex_(NULL), gogo_(gogo), var_(var),
        statements_added_(added)
  { go_assert(var->is_global()); }

  // We use the default copy constructor and assignment operator.

  // Insert S before the statement we are traversing, or before the
  // initialization expression of a global variable.
  void
  insert(Statement* s);

 private:
  // The block that the statement is in.
  Block* block_;
  // The index of the statement that we are traversing.
  size_t* pindex_;
  // The IR, needed when looking at an initializer expression for a
  // global variable.
  Gogo* gogo_;
  // The global variable, when looking at an initializer expression.
  Variable* var_;
  // If non-null, a set to record new statements inserted (non-owned).
  Statements* statements_added_;
};

// When translating the gogo IR into the backend data structure, this
// is the context we pass down the blocks and statements.

class Translate_context
{
 public:
  Translate_context(Gogo* gogo, Named_object* function, Block* block,
		    Bblock* bblock)
    : gogo_(gogo), backend_(gogo->backend()), function_(function),
      block_(block), bblock_(bblock), is_const_(false)
  { }

  // Accessors.

  Gogo*
  gogo()
  { return this->gogo_; }

  Backend*
  backend()
  { return this->backend_; }

  Named_object*
  function()
  { return this->function_; }

  Block*
  block()
  { return this->block_; }

  Bblock*
  bblock()
  { return this->bblock_; }

  bool
  is_const()
  { return this->is_const_; }

  // Make a constant context.
  void
  set_is_const()
  { this->is_const_ = true; }

 private:
  // The IR for the entire compilation unit.
  Gogo* gogo_;
  // The generator for the backend data structures.
  Backend* backend_;
  // The function we are currently translating.  NULL if not in a
  // function, e.g., the initializer of a global variable.
  Named_object* function_;
  // The block we are currently translating.  NULL if not in a
  // function.
  Block *block_;
  // The backend representation of the current block.  NULL if block_
  // is NULL.
  Bblock* bblock_;
  // Whether this is being evaluated in a constant context.  This is
  // used for type descriptor initializers.
  bool is_const_;
};

// This is used by some of the langhooks.
extern Gogo* go_get_gogo();

// Whether we have seen any errors.  FIXME: Replace with a backend
// interface.
extern bool saw_errors();

// For use in the debugger
extern void debug_go_gogo(Gogo*);
extern void debug_go_named_object(Named_object*);
extern void debug_go_bindings(Bindings*);


#endif // !defined(GO_GOGO_H)
