Mercurial > projects > ddmd
comparison dmd/DotTemplateInstanceExp.d @ 130:60bb0fe4563e
dmdfe 2.037 first main iteration
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Thu, 09 Sep 2010 22:51:44 +0100 |
parents | e28b18c23469 |
children | e3afd1303184 |
comparison
equal
deleted
inserted
replaced
129:010eb8f0e18d | 130:60bb0fe4563e |
---|---|
1 module dmd.DotTemplateInstanceExp; | 1 module dmd.DotTemplateInstanceExp; |
2 | 2 |
3 import dmd.common; | 3 import dmd.common; |
4 import dmd.ArrayTypes; | |
4 import dmd.Expression; | 5 import dmd.Expression; |
5 import dmd.UnaExp; | 6 import dmd.UnaExp; |
6 import dmd.OutBuffer; | 7 import dmd.OutBuffer; |
7 import dmd.Loc; | 8 import dmd.Loc; |
8 import dmd.Scope; | 9 import dmd.Scope; |
21 import dmd.Identifier; | 22 import dmd.Identifier; |
22 import dmd.ErrorExp; | 23 import dmd.ErrorExp; |
23 import dmd.DotVarExp; | 24 import dmd.DotVarExp; |
24 import dmd.TemplateDeclaration; | 25 import dmd.TemplateDeclaration; |
25 import dmd.Dsymbol; | 26 import dmd.Dsymbol; |
27 import dmd.DotTemplateExp; | |
28 import dmd.DotIdExp; | |
29 import dmd.TemplateExp; | |
30 import dmd.DsymbolExp; | |
26 | 31 |
27 import dmd.expression.Util; | 32 import dmd.expression.Util; |
28 | 33 |
29 /* Things like: | 34 /* Things like: |
30 * foo.bar!(args) | 35 * foo.bar!(args) |
31 */ | 36 */ |
32 class DotTemplateInstanceExp : UnaExp | 37 class DotTemplateInstanceExp : UnaExp |
33 { | 38 { |
34 TemplateInstance ti; | 39 TemplateInstance ti; |
35 | 40 |
36 this(Loc loc, Expression e, TemplateInstance ti) | 41 this(Loc loc, Expression e, Identifier name, Objects tiargs) |
37 { | 42 { |
38 super(loc, TOK.TOKdotti, DotTemplateInstanceExp.sizeof, e); | 43 super(loc, TOK.TOKdotti, DotTemplateInstanceExp.sizeof, e); |
39 //printf("DotTemplateInstanceExp()\n"); | 44 //printf("DotTemplateInstanceExp()\n"); |
40 this.ti = ti; | 45 this.ti = new TemplateInstance(loc, name); |
46 this.ti.tiargs = tiargs; | |
41 } | 47 } |
42 | 48 |
43 override Expression syntaxCopy() | 49 override Expression syntaxCopy() |
44 { | 50 { |
45 DotTemplateInstanceExp de = new DotTemplateInstanceExp(loc, e1.syntaxCopy(), cast(TemplateInstance)ti.syntaxCopy(null)); | 51 DotTemplateInstanceExp de = new DotTemplateInstanceExp(loc, e1.syntaxCopy(), ti.name, TemplateInstance.arraySyntaxCopy(ti.tiargs)); |
46 return de; | 52 return de; |
47 } | 53 } |
48 | 54 |
55 TemplateDeclaration getTempdecl(Scope sc) | |
56 { | |
57 version(LOGSEMANTIC) { | |
58 printf("DotTemplateInstanceExp::getTempdecl('%s')\n", toChars()); | |
59 } | |
60 if (!ti.tempdecl) | |
61 { | |
62 Expression e = new DotIdExp(loc, e1, ti.name); | |
63 e = e.semantic(sc); | |
64 if (e.op == TOKdottd) | |
65 { | |
66 auto dte = cast(DotTemplateExp)e; | |
67 ti.tempdecl = dte.td; | |
68 } | |
69 else if (e.op == TOKimport) | |
70 { | |
71 auto se = cast(ScopeExp)e; | |
72 ti.tempdecl = se.sds.isTemplateDeclaration(); | |
73 } | |
74 } | |
75 return ti.tempdecl; | |
76 } | |
77 | |
49 override Expression semantic(Scope sc) | 78 override Expression semantic(Scope sc) |
50 { | 79 { |
51 Dsymbol s; | 80 version (LOGSEMANTIC) { |
52 Dsymbol s2; | |
53 TemplateDeclaration td; | |
54 Expression e; | |
55 Identifier id; | |
56 Type t1; | |
57 Expression eleft = null; | |
58 Expression eright; | |
59 | |
60 version (LOGSEMANTIC) { | |
61 printf("DotTemplateInstanceExp.semantic('%s')\n", toChars()); | 81 printf("DotTemplateInstanceExp.semantic('%s')\n", toChars()); |
62 } | 82 } |
63 //e1.print(); | 83 Expression eleft; |
64 //print(); | 84 Expression e = new DotIdExp(loc, e1, ti.name); |
65 e1 = e1.semantic(sc); | 85 L1: |
66 t1 = e1.type; | 86 e = e.semantic(sc); |
67 if (t1) | 87 if (e.op == TOKdottd) |
68 t1 = t1.toBasetype(); | |
69 //t1.print(); | |
70 | |
71 /* Extract the following from e1: | |
72 * s: the symbol which ti should be a member of | |
73 * eleft: if not null, it is the 'this' pointer for ti | |
74 */ | |
75 | |
76 if (e1.op == TOKdotexp) | |
77 { | |
78 DotExp de = cast(DotExp)e1; | |
79 eleft = de.e1; | |
80 eright = de.e2; | |
81 } | |
82 else | |
83 { | |
84 eleft = null; | |
85 eright = e1; | |
86 } | |
87 if (eright.op == TOKimport) | |
88 { | 88 { |
89 s = (cast(ScopeExp)eright).sds; | 89 DotTemplateExp dte = cast(DotTemplateExp )e; |
90 } | 90 TemplateDeclaration td = dte.td; |
91 else if (e1.op == TOKtype) | 91 eleft = dte.e1; |
92 { | 92 ti.tempdecl = td; |
93 s = t1.isClassHandle(); | 93 ti.semantic(sc); |
94 if (!s) | 94 Dsymbol s = ti.inst.toAlias(); |
95 Declaration v = s.isDeclaration(); | |
96 if (v) | |
95 { | 97 { |
96 if (t1.ty == Tstruct) | |
97 s = (cast(TypeStruct)t1).sym; | |
98 else | |
99 goto L1; | |
100 } | |
101 } | |
102 else if (t1 && (t1.ty == Tstruct || t1.ty == Tclass)) | |
103 { | |
104 s = t1.toDsymbol(sc); | |
105 eleft = e1; | |
106 } | |
107 else if (t1 && t1.ty == Tpointer) | |
108 { | |
109 t1 = (cast(TypePointer)t1).next.toBasetype(); | |
110 if (t1.ty != Tstruct) | |
111 goto L1; | |
112 s = t1.toDsymbol(sc); | |
113 eleft = e1; | |
114 } | |
115 else | |
116 { | |
117 L1: | |
118 error("template %s is not a member of %s", ti.toChars(), e1.toChars()); | |
119 goto Lerr; | |
120 } | |
121 | |
122 assert(s); | |
123 id = ti.name; | |
124 s2 = s.search(loc, id, 0); | |
125 if (!s2) | |
126 { | |
127 if (!s.ident) | |
128 error("template identifier %s is not a member of undefined %s", id.toChars(), s.kind()); | |
129 else | |
130 error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.ident.toChars()); | |
131 goto Lerr; | |
132 } | |
133 s = s2; | |
134 s.semantic(sc); | |
135 s = s.toAlias(); | |
136 td = s.isTemplateDeclaration(); | |
137 if (!td) | |
138 { | |
139 error("%s is not a template", id.toChars()); | |
140 goto Lerr; | |
141 } | |
142 if (global.errors) | |
143 goto Lerr; | |
144 | |
145 ti.tempdecl = td; | |
146 | |
147 if (eleft) | |
148 { | |
149 Declaration v; | |
150 | |
151 ti.semantic(sc); | |
152 s = ti.inst.toAlias(); | |
153 v = s.isDeclaration(); | |
154 if (v) | |
155 { | |
156 e = new DotVarExp(loc, eleft, v); | 98 e = new DotVarExp(loc, eleft, v); |
157 e = e.semantic(sc); | 99 e = e.semantic(sc); |
158 return e; | 100 return e; |
159 } | 101 } |
102 e = new ScopeExp(loc, ti); | |
103 e = new DotExp(loc, eleft, e); | |
104 e = e.semantic(sc); | |
105 return e; | |
160 } | 106 } |
107 else if (e.op == TOKimport) | |
108 { | |
109 auto se = cast(ScopeExp)e; | |
110 TemplateDeclaration td = se.sds.isTemplateDeclaration(); | |
111 if (!td) | |
112 { | |
113 error("%s is not a template", e.toChars()); | |
114 return new ErrorExp(); | |
115 } | |
116 ti.tempdecl = td; | |
117 e = new ScopeExp(loc, ti); | |
118 e = e.semantic(sc); | |
119 return e; | |
120 } | |
121 else if (e.op == TOKdotexp) | |
122 { | |
123 DotExp de = cast(DotExp )e; | |
161 | 124 |
162 e = new ScopeExp(loc, ti); | 125 if (de.e2.op == TOKimport) |
163 if (eleft) | 126 { |
164 { | 127 // This should *really* be moved to ScopeExp::semantic() |
165 e = new DotExp(loc, eleft, e); | 128 ScopeExp se = cast(ScopeExp )de.e2; |
129 de.e2 = new DsymbolExp(loc, se.sds); | |
130 de.e2 = de.e2.semantic(sc); | |
131 } | |
132 | |
133 if (de.e2.op == TOKtemplate) | |
134 { | |
135 auto te = cast(TemplateExp) de.e2; | |
136 e = new DotTemplateExp(loc,de.e1,te.td); | |
137 } | |
138 goto L1; | |
166 } | 139 } |
167 e = e.semantic(sc); | 140 error("%s isn't a template", e.toChars()); |
168 return e; | |
169 | |
170 Lerr: | |
171 return new ErrorExp(); | 141 return new ErrorExp(); |
172 } | 142 } |
173 | 143 |
174 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) | 144 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
175 { | 145 { |