diff gcc/go/gofrontend/gogo.h @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/go/gofrontend/gogo.h	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/go/gofrontend/gogo.h	Thu Oct 25 07:37:49 2018 +0900
@@ -12,9 +12,7 @@
 class Traverse;
 class Statement_inserter;
 class Type;
-class Type_hash_identical;
 class Type_equal;
-class Type_identical;
 class Typed_identifier;
 class Typed_identifier_list;
 class Function_type;
@@ -117,7 +115,7 @@
 // For sorting purposes.
 
 struct Import_init_lt {
-  bool operator()(const Import_init* i1, const Import_init* i2)
+  bool operator()(const Import_init* i1, const Import_init* i2) const
   {
     return i1->init_name() < i2->init_name();
   }
@@ -318,6 +316,30 @@
   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 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.
@@ -658,6 +680,10 @@
   void
   tag_function(Escape_context*, Named_object*);
 
+  // Reclaim memory of escape analysis Nodes.
+  void
+  reclaim_escape_nodes();
+
   // Do all exports.
   void
   do_exports();
@@ -773,7 +799,7 @@
 
   // Return the name to use for a generated stub method.
   std::string
-  stub_method_name(const std::string& method_name);
+  stub_method_name(const Package*, const std::string& method_name);
 
   // Return the names of the hash and equality functions for TYPE.
   void
@@ -798,7 +824,7 @@
   // 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.
-  static std::string
+  std::string
   thunk_name();
 
   // Return whether an object is a thunk.
@@ -810,12 +836,8 @@
   init_function_name();
 
   // Return the name to use for a nested function.
-  static std::string
-  nested_function_name();
-
-  // Return the index of a nested function name.
-  static int
-  nested_function_num(const std::string&);
+  std::string
+  nested_function_name(Named_object* enclosing);
 
   // Return the name to use for a sink funciton.
   std::string
@@ -863,6 +885,12 @@
   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
@@ -911,6 +939,9 @@
                    std::vector<Bstatement*>&,
                    Bfunction* init_bfunction);
 
+  void
+  propagate_writebarrierrec();
+
   Named_object*
   write_barrier_variable();
 
@@ -1025,6 +1056,12 @@
   // 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_;
+  // 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.
@@ -1203,6 +1240,11 @@
   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)
@@ -1220,6 +1262,14 @@
     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
@@ -1427,13 +1477,14 @@
   // Export a function with a type.
   static void
   export_func_with_type(Export*, const std::string& name,
-			const Function_type*);
+			const Function_type*, bool nointerface);
 
   // Import a function.
   static void
   import_func(Import*, std::string* pname, Typed_identifier** receiver,
 	      Typed_identifier_list** pparameters,
-	      Typed_identifier_list** presults, bool* is_varargs);
+	      Typed_identifier_list** presults, bool* is_varargs,
+	      bool* nointerface);
 
  private:
   // Type for mapping from label names to Label objects.
@@ -1480,6 +1531,8 @@
   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.
@@ -1556,6 +1609,10 @@
   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_; }
@@ -1565,6 +1622,11 @@
   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)
@@ -1572,6 +1634,16 @@
     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();
+
   // 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
@@ -1596,7 +1668,10 @@
   // Export a function declaration.
   void
   export_func(Export* exp, const std::string& name) const
-  { Function::export_func_with_type(exp, name, this->fntype_); }
+  {
+    Function::export_func_with_type(exp, name, this->fntype_,
+				    this->is_method() && this->nointerface());
+  }
 
   // Check that the types used in this declaration's signature are defined.
   void
@@ -1853,6 +1928,20 @@
     this->in_unique_section_ = 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);
@@ -1953,6 +2042,9 @@
   // Whether this variable escapes the function it is created in.  This is
   // true until shown otherwise.
   bool escapes_ : 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
@@ -2074,6 +2166,9 @@
   type() const
   { return this->type_; }
 
+  void
+  set_type(Type* t);
+
   Expression*
   expr() const
   { return this->expr_; }
@@ -3223,13 +3318,14 @@
 {
  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_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)
@@ -3294,6 +3390,11 @@
   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
@@ -3319,19 +3420,24 @@
 class Statement_inserter
 {
  public:
+  typedef Unordered_set(Statement*) Statements;
+
   // Empty constructor.
   Statement_inserter()
-    : block_(NULL), pindex_(NULL), gogo_(NULL), var_(NULL)
+      : 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)
-    : block_(block), pindex_(pindex), gogo_(NULL), var_(NULL)
+  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)
-    : block_(NULL), pindex_(NULL), gogo_(gogo), var_(var)
+  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.
@@ -3351,6 +3457,8 @@
   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