compiler: pass a single flags argument to Backend::function
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
This commit is contained in:
parent
943cc2fb64
commit
a4e30bef64
@ -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.
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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++:
|
||||
|
||||
@ -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_;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user