Line data Source code
1 : /* valapointerindirection.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 :
24 : /**
25 : * Represents a pointer indirection.
26 : *
27 : * {{{ *foo }}}
28 : */
29 16735 : public class Vala.PointerIndirection : Expression {
30 : /**
31 : * The pointer to dereference.
32 : */
33 : public Expression inner {
34 194719 : get {
35 194719 : return _inner;
36 : }
37 15206 : private set {
38 29385 : _inner = value;
39 15206 : _inner.parent_node = this;
40 : }
41 : }
42 :
43 15206 : private Expression _inner;
44 :
45 : /**
46 : * Creates a new pointer indirection.
47 : *
48 : * @param inner pointer to be dereferenced
49 : * @return newly created pointer indirection
50 : */
51 45618 : public PointerIndirection (Expression inner, SourceReference? source_reference = null) {
52 15206 : this.source_reference = source_reference;
53 15206 : this.inner = inner;
54 : }
55 :
56 68682 : public override void accept (CodeVisitor visitor) {
57 68682 : visitor.visit_pointer_indirection (this);
58 :
59 68682 : visitor.visit_expression (this);
60 : }
61 :
62 68682 : public override void accept_children (CodeVisitor visitor) {
63 68682 : inner.accept (visitor);
64 : }
65 :
66 0 : public override void replace_expression (Expression old_node, Expression new_node) {
67 0 : if (inner == old_node) {
68 0 : inner = new_node;
69 : }
70 : }
71 :
72 0 : public override bool is_pure () {
73 0 : return inner.is_pure ();
74 : }
75 :
76 0 : public override bool is_accessible (Symbol sym) {
77 0 : return inner.is_accessible (sym);
78 : }
79 :
80 30009 : public override void get_error_types (Collection<DataType> collection, SourceReference? source_reference = null) {
81 30009 : inner.get_error_types (collection, source_reference);
82 : }
83 :
84 17014 : public override bool check (CodeContext context) {
85 17014 : if (checked) {
86 2834 : return !error;
87 : }
88 :
89 14180 : checked = true;
90 :
91 14180 : if (!inner.check (context)) {
92 2 : return false;
93 : }
94 14180 : if (inner.value_type == null) {
95 0 : error = true;
96 0 : Report.error (source_reference, "internal error: unknown type of inner expression");
97 0 : return false;
98 : }
99 28358 : if (inner.value_type is PointerType) {
100 14179 : var pointer_type = (PointerType) inner.value_type;
101 14179 : if (pointer_type.base_type is ReferenceType || pointer_type.base_type is VoidType) {
102 1 : error = true;
103 1 : Report.error (source_reference, "Pointer indirection not supported for this expression");
104 1 : return false;
105 : }
106 14178 : value_type = pointer_type.base_type;
107 14178 : value_type.value_owned = false;
108 : } else {
109 1 : error = true;
110 1 : Report.error (source_reference, "Pointer indirection not supported for this expression");
111 1 : return false;
112 : }
113 :
114 14178 : return !error;
115 : }
116 :
117 71 : public override void emit (CodeGenerator codegen) {
118 71 : inner.emit (codegen);
119 :
120 71 : codegen.visit_pointer_indirection (this);
121 :
122 71 : codegen.visit_expression (this);
123 : }
124 :
125 28977 : public override void get_defined_variables (Collection<Variable> collection) {
126 28977 : inner.get_defined_variables (collection);
127 : }
128 :
129 8691 : public override void get_used_variables (Collection<Variable> collection) {
130 8691 : inner.get_used_variables (collection);
131 : }
132 :
133 0 : public override string to_string () {
134 0 : return "(*%s)".printf (inner.to_string ());
135 : }
136 : }
|