72
|
1 module dmd.FuncExp;
|
|
2
|
|
3 import dmd.Expression;
|
|
4 import dmd.backend.elem;
|
|
5 import dmd.OutBuffer;
|
|
6 import dmd.Loc;
|
|
7 import dmd.Scope;
|
|
8 import dmd.InlineCostState;
|
|
9 import dmd.IRState;
|
|
10 import dmd.HdrGenState;
|
|
11 import dmd.FuncLiteralDeclaration;
|
0
|
12 import dmd.TOK;
|
|
13 import dmd.TypeFunction;
|
|
14 import dmd.TypeDelegate;
|
|
15 import dmd.TY;
|
|
16 import dmd.Type;
|
|
17 import dmd.Global;
|
|
18
|
|
19 import dmd.backend.Util;
|
|
20 import dmd.codegen.Util;
|
|
21 import dmd.backend.TYM;
|
72
|
22 import dmd.backend.Symbol;
|
|
23
|
0
|
24 class FuncExp : Expression
|
|
25 {
|
|
26 FuncLiteralDeclaration fd;
|
|
27
|
|
28 this(Loc loc, FuncLiteralDeclaration fd)
|
|
29 {
|
|
30 super(loc, TOK.TOKfunction, FuncExp.sizeof);
|
|
31 this.fd = fd;
|
|
32 }
|
|
33
|
72
|
34 override Expression syntaxCopy()
|
0
|
35 {
|
56
|
36 return new FuncExp(loc, cast(FuncLiteralDeclaration)fd.syntaxCopy(null));
|
0
|
37 }
|
|
38
|
72
|
39 override Expression semantic(Scope sc)
|
0
|
40 {
|
|
41 version (LOGSEMANTIC) {
|
|
42 printf("FuncExp.semantic(%s)\n", toChars());
|
|
43 }
|
|
44 if (!type)
|
|
45 {
|
|
46 fd.semantic(sc);
|
|
47
|
|
48 //fd.parent = sc.parent;
|
|
49 if (global.errors)
|
|
50 {
|
|
51 }
|
|
52 else
|
|
53 {
|
|
54 fd.semantic2(sc);
|
|
55 if (!global.errors ||
|
|
56 // need to infer return type
|
|
57 (fd.type && fd.type.ty == TY.Tfunction && !fd.type.nextOf()))
|
|
58 {
|
|
59 fd.semantic3(sc);
|
|
60
|
|
61 if (!global.errors && global.params.useInline)
|
|
62 fd.inlineScan();
|
|
63 }
|
|
64 }
|
|
65
|
|
66 // need to infer return type
|
|
67 if (global.errors && fd.type && fd.type.ty == TY.Tfunction && !fd.type.nextOf())
|
|
68 (cast(TypeFunction)fd.type).next = Type.terror;
|
|
69
|
|
70 // Type is a "delegate to" or "pointer to" the function literal
|
|
71 if (fd.isNested())
|
|
72 {
|
|
73 type = new TypeDelegate(fd.type);
|
|
74 type = type.semantic(loc, sc);
|
|
75 }
|
|
76 else
|
|
77 {
|
|
78 type = fd.type.pointerTo();
|
|
79 }
|
|
80
|
|
81 fd.tookAddressOf++;
|
|
82 }
|
|
83
|
|
84 return this;
|
|
85 }
|
|
86
|
72
|
87 override void scanForNestedRef(Scope sc)
|
0
|
88 {
|
|
89 assert(false);
|
|
90 }
|
|
91
|
72
|
92 override string toChars()
|
0
|
93 {
|
58
|
94 return fd.toChars();
|
0
|
95 }
|
|
96
|
72
|
97 override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
|
0
|
98 {
|
|
99 assert(false);
|
|
100 }
|
|
101
|
72
|
102 override elem* toElem(IRState* irs)
|
0
|
103 {
|
|
104 elem* e;
|
|
105 Symbol* s;
|
|
106
|
|
107 //printf("FuncExp::toElem() %s\n", toChars());
|
|
108 s = fd.toSymbol();
|
|
109 e = el_ptr(s);
|
|
110 if (fd.isNested())
|
|
111 {
|
|
112 elem* ethis = getEthis(loc, irs, fd);
|
|
113 e = el_pair(TYM.TYullong, ethis, e);
|
|
114 }
|
|
115
|
|
116 irs.deferToObj.push(cast(void*)fd);
|
|
117 el_setLoc(e,loc);
|
|
118 return e;
|
|
119 }
|
|
120
|
72
|
121 override int inlineCost(InlineCostState* ics)
|
0
|
122 {
|
|
123 assert(false);
|
|
124 }
|
|
125 }
|
|
126
|