diff options
author | Chris Manghane <cmang@google.com> | 2013-10-11 03:15:33 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-10-11 03:15:33 +0000 |
commit | f7191ecdbd3adad32b561db40fac6978df6409fe (patch) | |
tree | 5f41fdf78ab663a67c63db5beabf5b7175f799ba /gcc/go/go-gcc.cc | |
parent | cf5e3504b55071f73420c3ab7756200b1dad7b7a (diff) | |
download | gcc-f7191ecdbd3adad32b561db40fac6978df6409fe.zip gcc-f7191ecdbd3adad32b561db40fac6978df6409fe.tar.gz gcc-f7191ecdbd3adad32b561db40fac6978df6409fe.tar.bz2 |
compiler: Use backend interface for function declarations.
* go-gcc.cc (Backend::error_function): New function.
(Backend::function): New function.
(Backend::make_function): New function.
(function_to_tree): New function.
From-SVN: r203403
Diffstat (limited to 'gcc/go/go-gcc.cc')
-rw-r--r-- | gcc/go/go-gcc.cc | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index fcfd41b..6b77d94 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -334,6 +334,17 @@ class Gcc_backend : public Backend Bexpression* label_address(Blabel*, Location); + // Functions. + + Bfunction* + error_function() + { return this->make_function(error_mark_node); } + + 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 in_unique_section, Location); + private: // Make a Bexpression from a tree. Bexpression* @@ -350,6 +361,10 @@ class Gcc_backend : public Backend make_type(tree t) { return new Btype(t); } + Bfunction* + make_function(tree t) + { return new Bfunction(t); } + Btype* fill_in_struct(Btype*, const std::vector<Btyped_identifier>&); @@ -1724,6 +1739,56 @@ Gcc_backend::label_address(Blabel* label, Location location) return this->make_expression(ret); } +// Declare or define a new function. + +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 in_unique_section, + Location location) +{ + tree functype = fntype->get_tree(); + if (functype != error_mark_node) + { + gcc_assert(FUNCTION_POINTER_TYPE_P(functype)); + functype = TREE_TYPE(functype); + } + tree id = get_identifier_from_string(name); + if (functype == error_mark_node || id == error_mark_node) + return this->error_function(); + + 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) + TREE_PUBLIC(decl) = 1; + if (is_declaration) + DECL_EXTERNAL(decl) = 1; + else + { + tree restype = TREE_TYPE(functype); + tree resdecl = + build_decl(location.gcc_location(), RESULT_DECL, NULL_TREE, restype); + DECL_ARTIFICIAL(resdecl) = 1; + DECL_IGNORED_P(resdecl) = 1; + DECL_CONTEXT(resdecl) = decl; + DECL_RESULT(decl) = resdecl; + } + if (!is_inlinable) + DECL_UNINLINABLE(decl) = 1; + if (disable_split_stack) + { + tree attr = get_identifier("__no_split_stack__"); + DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE); + } + if (in_unique_section) + resolve_unique_section(decl, 0, 1); + + go_preserve_from_gc(decl); + return new Bfunction(decl); +} + // The single backend. static Gcc_backend gcc_backend; @@ -1799,3 +1864,9 @@ var_to_tree(Bvariable* bv) { return bv->get_tree(); } + +tree +function_to_tree(Bfunction* bf) +{ + return bf->get_tree(); +} |