compiler: pass a single flags argument to Backend::function
authorIan Lance Taylor <iant@golang.org>
Mon, 29 Oct 2018 19:25:57 +0000 (19:25 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 29 Oct 2018 19:25:57 +0000 (19:25 +0000)
    Reviewed-on: https://go-review.googlesource.com/c/145319

* go-gcc.cc (Gcc_backend::function): Change to use a single flags
parameter.

From-SVN: r265599

gcc/go/ChangeLog
gcc/go/go-gcc.cc
gcc/go/gofrontend/MERGE
gcc/go/gofrontend/backend.h
gcc/go/gofrontend/gogo.cc

index 915630daec98427a8fe25452e0dbc6296c98c399..e6f8644441fc1b16bd85d0203bb557bf2abf940b 100644 (file)
@@ -1,3 +1,8 @@
+2018-10-29  Ian Lance Taylor  <iant@golang.org>
+
+       * go-gcc.cc (Gcc_backend::function): Change to use a single flags
+       parameter.
+
 2018-10-29  Ian Lance Taylor  <iant@golang.org>
 
        * go-linemap.cc (Gcc_linemap::location_file): New method.
index 1a449b7cc470537a92c21ab3d4c0a0c9d1fa4234..9c317e06a922a64915d3fbd5f84a184c75f72945 100644 (file)
@@ -482,9 +482,7 @@ class Gcc_backend : public Backend
 
   Bfunction*
   function(Btype* fntype, const std::string& name, const std::string& asm_name,
-           bool is_visible, bool is_declaration, bool is_inlinable,
-           bool disable_split_stack, bool does_not_return,
-          bool in_unique_section, Location);
+          unsigned int flags, Location);
 
   Bstatement*
   function_defer_statement(Bfunction* function, Bexpression* undefer,
@@ -3047,10 +3045,8 @@ Gcc_backend::label_address(Blabel* label, Location location)
 
 Bfunction*
 Gcc_backend::function(Btype* fntype, const std::string& name,
-                      const std::string& asm_name, bool is_visible,
-                      bool is_declaration, bool is_inlinable,
-                      bool disable_split_stack, bool does_not_return,
-                     bool in_unique_section, Location location)
+                      const std::string& asm_name, unsigned int flags,
+                     Location location)
 {
   tree functype = fntype->get_tree();
   if (functype != error_mark_node)
@@ -3065,9 +3061,9 @@ Gcc_backend::function(Btype* fntype, const std::string& name,
   tree decl = build_decl(location.gcc_location(), FUNCTION_DECL, id, functype);
   if (! asm_name.empty())
     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
-  if (is_visible)
+  if ((flags & function_is_visible) != 0)
     TREE_PUBLIC(decl) = 1;
-  if (is_declaration)
+  if ((flags & function_is_declaration) != 0)
     DECL_EXTERNAL(decl) = 1;
   else
     {
@@ -3079,16 +3075,16 @@ Gcc_backend::function(Btype* fntype, const std::string& name,
       DECL_CONTEXT(resdecl) = decl;
       DECL_RESULT(decl) = resdecl;
     }
-  if (!is_inlinable)
+  if ((flags & function_is_inlinable) == 0)
     DECL_UNINLINABLE(decl) = 1;
-  if (disable_split_stack)
+  if ((flags & function_no_split_stack) != 0)
     {
       tree attr = get_identifier ("no_split_stack");
       DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE);
     }
-  if (does_not_return)
+  if ((flags & function_does_not_return) != 0)
     TREE_THIS_VOLATILE(decl) = 1;
-  if (in_unique_section)
+  if ((flags & function_in_unique_section) != 0)
     resolve_unique_section(decl, 0, 1);
 
   go_preserve_from_gc(decl);
index 7074d3e508adf4487e8ce5b1484cc3acad2a4faa..90ba4494aa6c6335422b875e65c3638fa956b598 100644 (file)
@@ -1,4 +1,4 @@
-e4a421a01ad1fcc4315e530e79272604f3683051
+8dae05f57f3c8249319e3360b10f07dcc2cd57a7
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 5cc0dec4a88480b9392451878b7076ac914d6e05..d2e93d24f49846c5118070a9709b03cc2b30611c 100644 (file)
@@ -699,26 +699,41 @@ class Backend
   virtual Bfunction*
   error_function() = 0;
 
+  // Bit flags to pass to the function method.
+
+  // Set if the function should be visible outside of the current
+  // compilation unit.
+  static const unsigned int function_is_visible = 1 << 0;
+
+  // Set if this is a function declaration rather than a definition;
+  // the definition will be in another compilation unit.
+  static const unsigned int function_is_declaration = 1 << 1;
+
+  // Set if the function can be inlined.  This is normally set, but is
+  // false for functions that may not be inlined because they call
+  // recover and must be visible for correct panic recovery.
+  static const unsigned int function_is_inlinable = 1 << 2;
+
+  // Set if the function may not split the stack.  This is set for the
+  // implementation of recover itself, among other things.
+  static const unsigned int function_no_split_stack = 1 << 3;
+
+  // Set if the function does not return.  This is set for the
+  // implementation of panic.
+  static const unsigned int function_does_not_return = 1 << 4;
+
+  // Set if the function should be put in a unique section if
+  // possible.  This is used for field tracking.
+  static const unsigned int function_in_unique_section = 1 << 5;
+
   // Declare or define a function of FNTYPE.
-  // NAME is the Go name of the function. ASM_NAME, if not the empty string, is
-  // the name that should be used in the symbol table; this will be non-empty if
-  // a magic extern comment is used.
-  // IS_VISIBLE is true if this function should be visible outside of the
-  // current compilation unit. IS_DECLARATION is true if this is a function
-  // declaration rather than a definition; the function definition will be in
-  // another compilation unit.
-  // IS_INLINABLE is true if the function can be inlined.
-  // DISABLE_SPLIT_STACK is true if this function may not split the stack; this
-  // is used for the implementation of recover.
-  // DOES_NOT_RETURN is true for a function that does not return; this is used
-  // for the implementation of panic.
-  // IN_UNIQUE_SECTION is true if this function should be put into a unique
-  // location if possible; this is used for field tracking.
+  // NAME is the Go name of the function.  ASM_NAME, if not the empty
+  // string, is the name that should be used in the symbol table; this
+  // will be non-empty if a magic extern comment is used.  FLAGS is
+  // bit flags described above.
   virtual Bfunction*
   function(Btype* fntype, const std::string& name, const std::string& asm_name,
-           bool is_visible, bool is_declaration, bool is_inlinable,
-           bool disable_split_stack, bool does_not_return,
-          bool in_unique_section, Location) = 0;
+          unsigned int flags, Location) = 0;
 
   // Create a statement that runs all deferred calls for FUNCTION.  This should
   // be a statement that looks like this in C++:
index 70af6273b017f65c14de2984f10f64cf99c47ea9..6ea247a989fec54c053ea4c3391703891af60b54 100644 (file)
@@ -719,10 +719,12 @@ Gogo::init_imports(std::vector<Bstatement*>& init_stmts, Bfunction *bfunction)
       const Import_init* ii = *p;
       std::string user_name = ii->package_name() + ".init";
       const std::string& init_name(ii->init_name());
-
+      const unsigned int flags =
+       (Backend::function_is_visible
+        | Backend::function_is_declaration
+        | Backend::function_is_inlinable);
       Bfunction* pfunc = this->backend()->function(fntype, user_name, init_name,
-                                                   true, true, true, false,
-                                                   false, false, unknown_loc);
+                                                  flags, unknown_loc);
       Bexpression* pfunc_code =
           this->backend()->function_code_expression(pfunc, unknown_loc);
       Bexpression* pfunc_call =
@@ -5521,7 +5523,7 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
 {
   if (this->fndecl_ == NULL)
     {
-      bool is_visible = false;
+      unsigned int flags = 0;
       bool is_init_fn = false;
       Type* rtype = NULL;
       if (no->package() != NULL)
@@ -5533,12 +5535,12 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
        ;
       else if (no->name() == gogo->get_init_fn_name())
        {
-         is_visible = true;
+         flags |= Backend::function_is_visible;
          is_init_fn = true;
        }
       else if (Gogo::unpack_hidden_name(no->name()) == "main"
                && gogo->is_main_package())
-        is_visible = true;
+       flags |= Backend::function_is_visible;
       // Methods have to be public even if they are hidden because
       // they can be pulled into type descriptors when using
       // anonymous fields.
@@ -5546,7 +5548,7 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
                || this->type_->is_method())
         {
          if (!this->is_unnamed_type_stub_method_)
-           is_visible = true;
+           flags |= Backend::function_is_visible;
          if (this->type_->is_method())
            rtype = this->type_->receiver()->type();
         }
@@ -5559,7 +5561,7 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
          // If an assembler name is explicitly specified, there must
          // be some reason to refer to the symbol from a different
          // object file.
-         is_visible = true;
+         flags |= Backend::function_is_visible;
        }
       else if (is_init_fn)
        {
@@ -5591,6 +5593,9 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
       if ((this->pragmas_ & GOPRAGMA_NOINLINE) != 0)
        is_inlinable = false;
 
+      if (is_inlinable)
+       flags |= Backend::function_is_inlinable;
+
       // If this is a thunk created to call a function which calls
       // the predeclared recover function, we need to disable
       // stack splitting for the thunk.
@@ -5600,20 +5605,22 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
       if ((this->pragmas_ & GOPRAGMA_NOSPLIT) != 0)
        disable_split_stack = true;
 
+      if (disable_split_stack)
+       flags |= Backend::function_no_split_stack;
+
       // This should go into a unique section if that has been
       // requested elsewhere, or if this is a nointerface function.
       // We want to put a nointerface function into a unique section
       // because there is a good chance that the linker garbage
       // collection can discard it.
-      bool in_unique_section = (this->in_unique_section_
-                               || (this->is_method() && this->nointerface()));
+      if (this->in_unique_section_
+         || (this->is_method() && this->nointerface()))
+       flags |= Backend::function_in_unique_section;
 
       Btype* functype = this->type_->get_backend_fntype(gogo);
       this->fndecl_ =
           gogo->backend()->function(functype, no->get_id(gogo), asm_name,
-                                    is_visible, false, is_inlinable,
-                                    disable_split_stack, false,
-                                   in_unique_section, this->location());
+                                   flags, this->location());
     }
   return this->fndecl_;
 }
@@ -5625,7 +5632,10 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
 {
   if (this->fndecl_ == NULL)
     {
-      bool does_not_return = false;
+      unsigned int flags =
+       (Backend::function_is_visible
+        | Backend::function_is_declaration
+        | Backend::function_is_inlinable);
 
       // Let Go code use an asm declaration to pick up a builtin
       // function.
@@ -5641,7 +5651,7 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
 
          if (this->asm_name_ == "runtime.gopanic"
              || this->asm_name_ == "__go_runtime_error")
-           does_not_return = true;
+           flags |= Backend::function_does_not_return;
        }
 
       std::string asm_name;
@@ -5658,8 +5668,7 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
       Btype* functype = this->fntype_->get_backend_fntype(gogo);
       this->fndecl_ =
           gogo->backend()->function(functype, no->get_id(gogo), asm_name,
-                                    true, true, true, false, does_not_return,
-                                   false, this->location());
+                                   flags, this->location());
     }
 
   return this->fndecl_;