Line data Source code
1 : /* valaaddressofexpression.vala
2 : *
3 : * Copyright (C) 2007-2010 Jürg Billeter
4 : *
5 : * This library is free software; you can redistribute it and/or
6 : * modify it under the terms of the GNU Lesser General Public
7 : * License as published by the Free Software Foundation; either
8 : * version 2.1 of the License, or (at your option) any later version.
9 :
10 : * This library is distributed in the hope that it will be useful,
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : * Lesser General Public License for more details.
14 :
15 : * You should have received a copy of the GNU Lesser General Public
16 : * License along with this library; if not, write to the Free Software
17 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 : *
19 : * Author:
20 : * Jürg Billeter <j@bitron.ch>
21 : */
22 :
23 : using GLib;
24 :
25 : /**
26 : * Represents an address-of expression.
27 : *
28 : * {{{ &foo }}}
29 : */
30 4612 : public class Vala.AddressofExpression : Expression {
31 : /**
32 : * The variable whose address is to be computed.
33 : */
34 : public Expression inner {
35 27755 : get {
36 27755 : return _inner;
37 : }
38 3083 : private set {
39 3083 : _inner = value;
40 3083 : _inner.parent_node = this;
41 : }
42 : }
43 :
44 3083 : private Expression _inner;
45 :
46 : /**
47 : * Creates a new address-of expression.
48 : *
49 : * @param inner variable whose address is to be computed
50 : * @return newly created address-of expression
51 : */
52 9249 : public AddressofExpression (Expression inner, SourceReference? source_reference = null) {
53 3083 : this.source_reference = source_reference;
54 3083 : this.inner = inner;
55 : }
56 :
57 7687 : public override void accept (CodeVisitor visitor) {
58 7687 : visitor.visit_addressof_expression (this);
59 :
60 7687 : visitor.visit_expression (this);
61 : }
62 :
63 7687 : public override void accept_children (CodeVisitor visitor) {
64 7687 : inner.accept (visitor);
65 : }
66 :
67 0 : public override string to_string () {
68 0 : return "(&%s)".printf (inner.to_string ());
69 : }
70 :
71 0 : public override void replace_expression (Expression old_node, Expression new_node) {
72 0 : if (inner == old_node) {
73 0 : inner = new_node;
74 : }
75 : }
76 :
77 0 : public override bool is_pure () {
78 0 : return inner.is_pure ();
79 : }
80 :
81 0 : public override bool is_accessible (Symbol sym) {
82 0 : return inner.is_accessible (sym);
83 : }
84 :
85 38 : public override bool is_non_null () {
86 38 : return inner.is_non_null ();
87 : }
88 :
89 2864 : public override bool check (CodeContext context) {
90 2864 : if (checked) {
91 9 : return !error;
92 : }
93 :
94 2855 : checked = true;
95 :
96 2855 : inner.lvalue = true;
97 :
98 2855 : if (!inner.check (context)) {
99 0 : error = true;
100 0 : return false;
101 : }
102 :
103 2855 : unowned ElementAccess? ea = inner as ElementAccess;
104 2855 : if (inner is MemberAccess && inner.symbol_reference is Variable) {
105 : // address of variable is always possible
106 2 : } else if (ea != null &&
107 1 : (ea.container.value_type is ArrayType || ea.container.value_type is PointerType)) {
108 : // address of element of regular array or pointer is always possible
109 : } else {
110 1 : error = true;
111 1 : Report.error (source_reference, "Address-of operator not supported for this expression");
112 1 : return false;
113 : }
114 :
115 2854 : if (inner.value_type.is_reference_type_or_type_parameter ()) {
116 1422 : value_type = new PointerType (new PointerType (inner.value_type), source_reference);
117 : } else {
118 1432 : value_type = new PointerType (inner.value_type, source_reference);
119 : }
120 :
121 2854 : return !error;
122 : }
123 :
124 24 : public override void emit (CodeGenerator codegen) {
125 24 : inner.emit (codegen);
126 :
127 24 : codegen.visit_addressof_expression (this);
128 :
129 24 : codegen.visit_expression (this);
130 : }
131 : }
|