comparison dmd/AliasDeclaration.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 5c9b78899f5d
comparison
equal deleted inserted replaced
-1:000000000000 0:10317f0c89a5
1 module dmd.AliasDeclaration;
2
3 import dmd.LINK;
4 import dmd.Declaration;
5 import dmd.TypedefDeclaration;
6 import dmd.VarDeclaration;
7 import dmd.FuncDeclaration;
8 import dmd.FuncAliasDeclaration;
9 import dmd.Dsymbol;
10 import dmd.ScopeDsymbol;
11 import dmd.Loc;
12 import dmd.Identifier;
13 import dmd.Type;
14 import dmd.OutBuffer;
15 import dmd.HdrGenState;
16 import dmd.Scope;
17 import dmd.STC;
18 import dmd.Expression;
19 import dmd.Global;
20
21 class AliasDeclaration : Declaration
22 {
23 Dsymbol aliassym;
24 Dsymbol overnext; // next in overload list
25 int inSemantic;
26
27 this(Loc loc, Identifier ident, Type type)
28 {
29 super(ident);
30
31 //printf("AliasDeclaration(id = '%s', type = %p)\n", id.toChars(), type);
32 //printf("type = '%s'\n", type.toChars());
33 this.loc = loc;
34 this.type = type;
35 this.aliassym = null;
36 version (_DH) {
37 this.htype = null;
38 this.haliassym = null;
39 }
40
41 assert(type);
42 }
43
44 this(Loc loc, Identifier id, Dsymbol s)
45 {
46 super(id);
47
48 //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s);
49 assert(s !is this); /// huh?
50 this.loc = loc;
51 this.type = null;
52 this.aliassym = s;
53 version (_DH) {
54 this.htype = null;
55 this.haliassym = null;
56 }
57 assert(s);
58 }
59
60 Dsymbol syntaxCopy(Dsymbol)
61 {
62 assert(false);
63 }
64
65 void semantic(Scope sc)
66 {
67 //printf("AliasDeclaration.semantic() %s\n", toChars());
68 if (aliassym)
69 {
70 if (aliassym.isTemplateInstance())
71 aliassym.semantic(sc);
72 return;
73 }
74 this.inSemantic = 1;
75
76 if (storage_class & STC.STCconst)
77 error("cannot be const");
78
79 storage_class |= sc.stc & STC.STCdeprecated;
80
81 // Given:
82 // alias foo.bar.abc def;
83 // it is not knowable from the syntax whether this is an alias
84 // for a type or an alias for a symbol. It is up to the semantic()
85 // pass to distinguish.
86 // If it is a type, then type is set and getType() will return that
87 // type. If it is a symbol, then aliassym is set and type is null -
88 // toAlias() will return aliasssym.
89
90 Dsymbol s;
91 Type t;
92 Expression e;
93
94 /* This section is needed because resolve() will:
95 * const x = 3;
96 * alias x y;
97 * try to alias y to 3.
98 */
99 s = type.toDsymbol(sc);
100 if (s && ((s.getType() && type.equals(s.getType())) || s.isEnumMember()))
101 goto L2; // it's a symbolic alias
102
103 ///version (DMDV2) {
104 if (storage_class & STC.STCref)
105 { // For 'ref' to be attached to function types, and picked
106 // up by Type.resolve(), it has to go into sc.
107 sc = sc.push();
108 sc.stc |= STC.STCref;
109 type.resolve(loc, sc, &e, &t, &s);
110 sc = sc.pop();
111 }
112 else
113 /// #endif
114 type.resolve(loc, sc, &e, &t, &s);
115 if (s)
116 {
117 goto L2;
118 }
119 else if (e)
120 {
121 // Try to convert Expression to Dsymbol
122 s = getDsymbol(e);
123 if (s)
124 goto L2;
125
126 error("cannot alias an expression %s", e.toChars());
127 t = e.type;
128 }
129 else if (t)
130 {
131 type = t;
132 }
133 if (overnext)
134 ScopeDsymbol.multiplyDefined(Loc(0), this, overnext);
135 this.inSemantic = 0;
136 return;
137
138 L2:
139 //printf("alias is a symbol %s %s\n", s.kind(), s.toChars());
140 type = null;
141 VarDeclaration v = s.isVarDeclaration();
142 if (v && v.linkage == LINK.LINKdefault)
143 {
144 error("forward reference of %s", v.toChars());
145 s = null;
146 }
147 else
148 {
149 FuncDeclaration f = s.toAlias().isFuncDeclaration();
150 if (f)
151 {
152 if (overnext)
153 {
154 FuncAliasDeclaration fa = new FuncAliasDeclaration(f);
155 if (!fa.overloadInsert(overnext))
156 ScopeDsymbol.multiplyDefined(Loc(0), f, overnext);
157 overnext = null;
158 s = fa;
159 s.parent = sc.parent;
160 }
161 }
162 if (overnext)
163 ScopeDsymbol.multiplyDefined(Loc(0), s, overnext);
164 if (s == this)
165 {
166 assert(global.errors);
167 s = null;
168 }
169 }
170 //printf("setting aliassym %p to %p\n", this, s);
171 aliassym = s;
172 this.inSemantic = 0;
173 }
174
175 bool overloadInsert(Dsymbol s)
176 {
177 /* Don't know yet what the aliased symbol is, so assume it can
178 * be overloaded and check later for correctness.
179 */
180
181 //printf("AliasDeclaration.overloadInsert('%s')\n", s.toChars());
182 if (overnext is null)
183 {
184 overnext = s;
185 return true;
186 }
187 else
188 {
189 return overnext.overloadInsert(s);
190 }
191 }
192
193 string kind()
194 {
195 return "alias";
196 }
197
198 Type getType()
199 {
200 return type;
201 }
202
203 Dsymbol toAlias()
204 {
205 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : "");
206 assert(this !is aliassym);
207 //static int count; if (++count == 10) *(char*)0=0;
208 if (inSemantic)
209 {
210 error("recursive alias declaration");
211 aliassym = new TypedefDeclaration(loc, ident, Type.terror, null);
212 }
213
214 Dsymbol s = aliassym ? aliassym.toAlias() : this;
215 return s;
216 }
217
218 void toCBuffer(OutBuffer buf, HdrGenState* hgs)
219 {
220 assert(false);
221 }
222
223 version (_DH) {
224 Type htype;
225 Dsymbol haliassym;
226 }
227 void toDocBuffer(OutBuffer buf)
228 {
229 assert(false);
230 }
231
232 AliasDeclaration isAliasDeclaration() { return this; }
233 }