Mercurial > projects > ddmd
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 } |