Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include <u.h> | 5 #include <u.h> |
6 #include <libc.h> | 6 #include <libc.h> |
7 #include "go.h" | 7 #include "go.h" |
8 #include "y.tab.h" | 8 #include "y.tab.h" |
9 | 9 |
10 static void dumpexporttype(Type *t); | 10 static void dumpexporttype(Type *t); |
11 | 11 |
12 // Mark n's symbol as exported | 12 // Mark n's symbol as exported |
13 void | 13 void |
14 exportsym(Node *n) | 14 exportsym(Node *n) |
15 { | 15 { |
16 if(n == N || n->sym == S) | 16 if(n == N || n->sym == S) |
17 return; | 17 return; |
18 if(n->sym->flags & (SymExport|SymPackage)) { | 18 if(n->sym->flags & (SymExport|SymPackage)) { |
19 if(n->sym->flags & SymPackage) | 19 if(n->sym->flags & SymPackage) |
20 yyerror("export/package mismatch: %S", n->sym); | 20 yyerror("export/package mismatch: %S", n->sym); |
21 return; | 21 return; |
22 } | 22 } |
23 n->sym->flags |= SymExport; | 23 n->sym->flags |= SymExport; |
24 | 24 |
25 if(debug['E']) | |
26 print("export symbol %S\n", n->sym); | |
25 exportlist = list(exportlist, n); | 27 exportlist = list(exportlist, n); |
26 } | 28 } |
27 | 29 |
28 // Mark n's symbol as package-local | |
29 static void | |
30 packagesym(Node *n) | |
31 { | |
32 if(n == N || n->sym == S) | |
33 return; | |
34 if(n->sym->flags & (SymExport|SymPackage)) { | |
35 if(n->sym->flags & SymExport) | |
36 yyerror("export/package mismatch: %S", n->sym); | |
37 return; | |
38 } | |
39 n->sym->flags |= SymPackage; | |
40 | |
41 exportlist = list(exportlist, n); | |
42 } | |
43 | |
44 int | 30 int |
45 exportname(char *s) | 31 exportname(char *s) |
46 { | 32 { |
47 Rune r; | 33 Rune r; |
48 | 34 |
49 if((uchar)s[0] < Runeself) | 35 if((uchar)s[0] < Runeself) |
50 return 'A' <= s[0] && s[0] <= 'Z'; | 36 return 'A' <= s[0] && s[0] <= 'Z'; |
51 chartorune(&r, s); | 37 chartorune(&r, s); |
52 return isupperrune(r); | 38 return isupperrune(r); |
53 } | 39 } |
54 | 40 |
55 static int | 41 static int |
56 initname(char *s) | 42 initname(char *s) |
57 { | 43 { |
58 return strcmp(s, "init") == 0; | 44 return strcmp(s, "init") == 0; |
59 } | 45 } |
60 | 46 |
47 // exportedsym returns whether a symbol will be visible | |
48 // to files that import our package. | |
49 static int | |
50 exportedsym(Sym *sym) | |
51 { | |
52 // Builtins are visible everywhere. | |
53 if(sym->pkg == builtinpkg || sym->origpkg == builtinpkg) | |
54 return 1; | |
55 | |
56 return sym->pkg == localpkg && exportname(sym->name); | |
57 } | |
58 | |
61 void | 59 void |
62 autoexport(Node *n, int ctxt) | 60 autoexport(Node *n, int ctxt) |
63 { | 61 { |
64 if(n == N || n->sym == S) | 62 if(n == N || n->sym == S) |
65 return; | 63 return; |
66 if((ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN) | 64 if((ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN) |
67 return; | 65 return; |
68 if(n->ntype && n->ntype->op == OTFUNC && n->ntype->left) // metho d | 66 if(n->ntype && n->ntype->op == OTFUNC && n->ntype->left) // metho d |
69 return; | 67 return; |
70 if(exportname(n->sym->name) || initname(n->sym->name)) | 68 if(exportname(n->sym->name) || initname(n->sym->name)) |
71 exportsym(n); | 69 exportsym(n); |
72 else | |
73 packagesym(n); | |
74 } | 70 } |
75 | 71 |
76 static void | 72 static void |
77 dumppkg(Pkg *p) | 73 dumppkg(Pkg *p) |
78 { | 74 { |
79 char *suffix; | 75 char *suffix; |
80 | 76 |
81 if(p == nil || p == localpkg || p->exported || p == builtinpkg) | 77 if(p == nil || p == localpkg || p->exported || p == builtinpkg) |
82 return; | 78 return; |
83 p->exported = 1; | 79 p->exported = 1; |
(...skipping 13 matching lines...) Expand all Loading... | |
97 } | 93 } |
98 | 94 |
99 static void | 95 static void |
100 reexportdep(Node *n) | 96 reexportdep(Node *n) |
101 { | 97 { |
102 Type *t; | 98 Type *t; |
103 | 99 |
104 if(!n) | 100 if(!n) |
105 return; | 101 return; |
106 | 102 |
107 //» print("reexportdep %+hN\n", n); | 103 » //print("reexportdep %+hN\n", n); |
108 switch(n->op) { | 104 switch(n->op) { |
109 case ONAME: | 105 case ONAME: |
110 switch(n->class&~PHEAP) { | 106 switch(n->class&~PHEAP) { |
111 case PFUNC: | 107 case PFUNC: |
112 // methods will be printed along with their type | 108 // methods will be printed along with their type |
113 » » » if(!n->type || n->type->thistuple > 0) | 109 » » » if(n->left && n->left->op == OTYPE) |
114 break; | 110 break; |
115 // fallthrough | 111 // fallthrough |
116 case PEXTERN: | 112 case PEXTERN: |
117 » » » if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg) | 113 » » » if(n->sym && !exportedsym(n->sym)) |
118 exportlist = list(exportlist, n); | 114 exportlist = list(exportlist, n); |
119 } | 115 } |
120 break; | 116 break; |
121 | 117 |
122 case ODCL: | 118 case ODCL: |
123 // Local variables in the bodies need their type. | 119 // Local variables in the bodies need their type. |
124 t = n->left->type; | 120 t = n->left->type; |
125 if(t != types[t->etype] && t != idealbool && t != idealstring) { | 121 if(t != types[t->etype] && t != idealbool && t != idealstring) { |
126 if(isptr[t->etype]) | 122 if(isptr[t->etype]) |
127 t = t->type; | 123 t = t->type; |
128 » » » if (t && t->sym && t->sym->def && t->sym->pkg != localpk g && t->sym->pkg != builtinpkg) { | 124 » » » if(t && t->sym && t->sym->def && !exportedsym(t->sym)) { |
129 exportlist = list(exportlist, t->sym->def); | 125 exportlist = list(exportlist, t->sym->def); |
130 } | 126 } |
131 } | 127 } |
132 break; | 128 break; |
133 | 129 |
134 case OLITERAL: | 130 case OLITERAL: |
135 t = n->type; | 131 t = n->type; |
136 if(t != types[n->type->etype] && t != idealbool && t != idealstr ing) { | 132 if(t != types[n->type->etype] && t != idealbool && t != idealstr ing) { |
137 if(isptr[t->etype]) | 133 if(isptr[t->etype]) |
138 t = t->type; | 134 t = t->type; |
139 » » » if (t && t->sym && t->sym->def && t->sym->pkg != localpk g && t->sym->pkg != builtinpkg) { | 135 » » » if(t && t->sym && t->sym->def && !exportedsym(t->sym)) { |
140 //» » » » print("reexport literal type %+hN\n", t->sym->de f); | 136 » » » » if(debug['E']) |
137 » » » » » print("reexport literal type %S\n", t->s ym); | |
141 exportlist = list(exportlist, t->sym->def); | 138 exportlist = list(exportlist, t->sym->def); |
142 } | 139 } |
143 } | 140 } |
144 // fallthrough | 141 // fallthrough |
145 case OTYPE: | 142 case OTYPE: |
146 » » if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinp kg) | 143 » » if(n->sym && !exportedsym(n->sym)) { |
144 » » » if(debug['E']) | |
145 » » » » print("reexport literal/type %S\n", n->sym); | |
147 exportlist = list(exportlist, n); | 146 exportlist = list(exportlist, n); |
147 } | |
148 break; | 148 break; |
149 | 149 |
150 // for operations that need a type when rendered, put the type on the ex port list. | 150 // for operations that need a type when rendered, put the type on the ex port list. |
151 case OCONV: | 151 case OCONV: |
152 case OCONVIFACE: | 152 case OCONVIFACE: |
153 case OCONVNOP: | 153 case OCONVNOP: |
154 case ODOTTYPE: | 154 case ODOTTYPE: |
155 case ODOTTYPE2: | 155 case ODOTTYPE2: |
156 case OSTRUCTLIT: | 156 case OSTRUCTLIT: |
157 case OPTRLIT: | 157 case OPTRLIT: |
158 t = n->type; | 158 t = n->type; |
159 if(!t->sym && t->type) | 159 if(!t->sym && t->type) |
160 t = t->type; | 160 t = t->type; |
161 » » if (t && t->sym && t->sym->def && t->sym->pkg != localpkg && t- >sym->pkg != builtinpkg) { | 161 » » if (t && t->sym && t->sym->def && !exportedsym(t->sym)) { |
aam
2012/12/01 17:29:57
if( like you did above.
remyoudompheng
2012/12/06 07:23:55
Done.
| |
162 //» » » print("reexport convnop %+hN\n", t->sym->def); | 162 » » » if(debug['E']) |
163 » » » » print("reexport type for convnop %S\n", t->sym); | |
163 exportlist = list(exportlist, t->sym->def); | 164 exportlist = list(exportlist, t->sym->def); |
164 } | 165 } |
165 break; | 166 break; |
166 } | 167 } |
167 | 168 |
168 reexportdep(n->left); | 169 reexportdep(n->left); |
169 reexportdep(n->right); | 170 reexportdep(n->right); |
170 reexportdeplist(n->list); | 171 reexportdeplist(n->list); |
171 reexportdeplist(n->rlist); | 172 reexportdeplist(n->rlist); |
172 reexportdeplist(n->ninit); | 173 reexportdeplist(n->ninit); |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 pt->nod = n; // unzero nod | 491 pt->nod = n; // unzero nod |
491 pt->sym->lastlineno = parserline(); | 492 pt->sym->lastlineno = parserline(); |
492 declare(n, PEXTERN); | 493 declare(n, PEXTERN); |
493 checkwidth(pt); | 494 checkwidth(pt); |
494 } else if(!eqtype(pt->orig, t)) | 495 } else if(!eqtype(pt->orig, t)) |
495 yyerror("inconsistent definition for type %S during import\n\t%l T\n\t%lT", pt->sym, pt, t); | 496 yyerror("inconsistent definition for type %S during import\n\t%l T\n\t%lT", pt->sym, pt, t); |
496 | 497 |
497 if(debug['E']) | 498 if(debug['E']) |
498 print("import type %T %lT\n", pt, t); | 499 print("import type %T %lT\n", pt, t); |
499 } | 500 } |
OLD | NEW |