Spicy
function.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <set>
6 #include <utility>
7 
8 #include <hilti/ast/attribute.h>
9 #include <hilti/ast/node.h>
10 #include <hilti/ast/statement.h>
11 #include <hilti/ast/type.h>
12 #include <hilti/ast/types/function.h>
13 
14 namespace hilti {
15 
16 namespace function {
17 
19 enum class CallingConvention {
20  Extern,
21  ExternNoSuspend,
22  Standard
23 };
24 
25 namespace detail {
26 constexpr util::enum_::Value<CallingConvention> conventions[] = {
27  {CallingConvention::Extern, "extern"},
28  {CallingConvention::ExternNoSuspend, "extern-no-suspend"},
29  {CallingConvention::Standard, "<standard>"},
30 };
31 } // namespace detail
32 
33 constexpr auto to_string(CallingConvention cc) { return util::enum_::to_string(cc, detail::conventions); }
34 
35 namespace calling_convention {
36 constexpr inline auto from_string(const std::string_view& s) {
37  return util::enum_::from_string<CallingConvention>(s, detail::conventions);
38 }
39 } // namespace calling_convention
40 
41 } // namespace function
42 
44 class Function : public NodeBase {
45 public:
46  Function(ID id, Type type, std::optional<Statement> body,
47  function::CallingConvention cc = function::CallingConvention::Standard,
48  std::optional<AttributeSet> attrs = {}, Meta m = Meta())
49  : NodeBase(nodes(std::move(id), std::move(type), std::move(body), std::move(attrs)), std::move(m)), _cc(cc) {}
50 
52 
53  const auto& id() const { return child<ID>(0); }
54  const auto& type() const { return child<Type>(1).as<Type>(); }
55  NodeRef typeRef() { return NodeRef(children()[1]); }
56  const auto& ftype() const { return child<Type>(1).as<type::Function>(); }
57  auto body() const { return children()[2].tryAs<Statement>(); }
58  auto attributes() const { return children()[3].tryAs<AttributeSet>(); }
59  auto callingConvention() const { return _cc; }
60  bool isStatic() const { return AttributeSet::find(attributes(), "&static").has_value(); }
61 
62  bool operator==(const Function& other) const {
63  return id() == other.id() && type() == other.type() && body() == other.body() &&
64  attributes() == other.attributes() && callingConvention() == other.callingConvention();
65  }
66 
67  void setBody(const Statement& b) { children()[2] = b; }
68  void setID(const ID& id) { children()[0] = id; }
69  void setFunctionType(const type::Function& ftype) { children()[1] = ftype; }
70  void setResultType(const Type& t) { children()[1].as<type::Function>().setResultType(t); }
71 
73  Node& _typeNode() { return children()[1]; }
74 
76  auto properties() const { return node::Properties{{"cc", to_string(_cc)}}; }
77 
78 private:
79  function::CallingConvention _cc = function::CallingConvention::Standard;
80 };
81 
83 inline Node to_node(Function f) { return Node(std::move(f)); }
84 
85 } // namespace hilti
Definition: function.h:71
const Node none
Definition: node.cc:14
Definition: function.h:44
Definition: meta.h:19
Definition: attribute.h:174
Definition: type.h:160
Node & _typeNode()
Definition: function.h:73
hilti::optional_ref< const Attribute > find(std::string_view tag) const
Definition: attribute.h:200
std::map< std::string, node::detail::PropertyValue > Properties
Definition: node.h:97
Definition: node.h:111
Definition: node-ref.h:45
Definition: id.h:18
Definition: node.h:359
auto properties() const
Definition: function.h:76