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 "go.h" | 5 #include "go.h" |
6 #include "md5.h" | 6 #include "md5.h" |
7 #include "y.tab.h" | 7 #include "y.tab.h" |
8 #include "opnames.h" | 8 #include "opnames.h" |
9 | 9 |
10 typedef struct Error Error; | 10 typedef struct Error Error; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 h = -h; | 249 h = -h; |
250 if(h < 0) | 250 if(h < 0) |
251 h = 0; | 251 h = 0; |
252 } | 252 } |
253 return h; | 253 return h; |
254 } | 254 } |
255 | 255 |
256 Sym* | 256 Sym* |
257 lookup(char *name) | 257 lookup(char *name) |
258 { | 258 { |
259 » return pkglookup(name, package); | 259 » return pkglookup(name, localpkg); |
260 } | 260 } |
261 | 261 |
262 Sym* | 262 Sym* |
263 pkglookup(char *name, char *pkg) | 263 pkglookup(char *name, Pkg *pkg) |
264 { | 264 { |
265 Sym *s; | 265 Sym *s; |
266 uint32 h; | 266 uint32 h; |
267 int c; | 267 int c; |
268 | 268 |
269 h = stringhash(name) % NHASH; | 269 h = stringhash(name) % NHASH; |
270 c = name[0]; | 270 c = name[0]; |
271 for(s = hash[h]; s != S; s = s->link) { | 271 for(s = hash[h]; s != S; s = s->link) { |
272 » » if(s->name[0] != c) | 272 » » if(s->name[0] != c || s->pkg != pkg) |
273 continue; | 273 continue; |
274 if(strcmp(s->name, name) == 0) | 274 if(strcmp(s->name, name) == 0) |
275 » » » if(s->package && strcmp(s->package, pkg) == 0) | 275 » » » return s; |
276 » » » » return s; | |
277 } | 276 } |
278 | 277 |
279 s = mal(sizeof(*s)); | 278 s = mal(sizeof(*s)); |
280 s->name = mal(strlen(name)+1); | 279 s->name = mal(strlen(name)+1); |
281 strcpy(s->name, name); | 280 strcpy(s->name, name); |
282 | 281 |
283 » // botch - should probably try to reuse the pkg string | 282 » s->pkg = pkg; |
284 » if(pkg == package) | |
285 » » s->package = package; | |
286 » else { | |
287 » » s->package = mal(strlen(pkg)+1); | |
288 » » strcpy(s->package, pkg); | |
289 » } | |
290 | |
291 » s->packagename = s->package; | |
292 | 283 |
293 s->link = hash[h]; | 284 s->link = hash[h]; |
294 hash[h] = s; | 285 hash[h] = s; |
295 s->lexical = LNAME; | 286 s->lexical = LNAME; |
296 | 287 |
297 return s; | 288 return s; |
298 } | 289 } |
299 | 290 |
300 Sym* | 291 Sym* |
301 restrictlookup(char *name, char *pkg) | 292 restrictlookup(char *name, Pkg *pkg) |
302 { | 293 { |
303 » if(!exportname(name) && strcmp(pkg, package) != 0) | 294 » if(!exportname(name) && pkg != localpkg) |
304 yyerror("cannot refer to unexported name %s.%s", pkg, name); | 295 yyerror("cannot refer to unexported name %s.%s", pkg, name); |
305 return pkglookup(name, pkg); | 296 return pkglookup(name, pkg); |
306 } | 297 } |
307 | 298 |
308 | 299 |
309 // find all the exported symbols in package opkg | 300 // find all the exported symbols in package opkg |
310 // and make them available in the current package | 301 // and make them available in the current package |
311 void | 302 void |
312 importdot(Sym *opkg, Node *pack) | 303 importdot(Pkg *opkg, Node *pack) |
313 { | 304 { |
314 Sym *s, *s1; | 305 Sym *s, *s1; |
315 uint32 h; | 306 uint32 h; |
316 » int c, n; | 307 » int n; |
317 | |
318 » if(strcmp(opkg->name, package) == 0) | |
319 » » return; | |
320 | 308 |
321 n = 0; | 309 n = 0; |
322 c = opkg->name[0]; | |
323 for(h=0; h<NHASH; h++) { | 310 for(h=0; h<NHASH; h++) { |
324 for(s = hash[h]; s != S; s = s->link) { | 311 for(s = hash[h]; s != S; s = s->link) { |
325 » » » if(s->package[0] != c) | 312 » » » if(s->pkg != opkg) |
326 continue; | 313 continue; |
327 if(!exportname(s->name) || utfrune(s->name, 0xb7))
// 0xb7 = center dot | 314 if(!exportname(s->name) || utfrune(s->name, 0xb7))
// 0xb7 = center dot |
328 continue; | 315 continue; |
329 if(strcmp(s->package, opkg->name) != 0) | |
330 continue; | |
331 s1 = lookup(s->name); | 316 s1 = lookup(s->name); |
332 if(s1->def != N) { | 317 if(s1->def != N) { |
333 redeclare(s1, "during import"); | 318 redeclare(s1, "during import"); |
334 continue; | 319 continue; |
335 } | 320 } |
336 s1->def = s->def; | 321 s1->def = s->def; |
337 s1->block = s->block; | 322 s1->block = s->block; |
338 s1->def->pack = pack; | 323 s1->def->pack = pack; |
339 n++; | 324 n++; |
340 } | 325 } |
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 strcpy(buf, ""); | 961 strcpy(buf, ""); |
977 | 962 |
978 out: | 963 out: |
979 return fmtstrcpy(fp, buf); | 964 return fmtstrcpy(fp, buf); |
980 } | 965 } |
981 | 966 |
982 int | 967 int |
983 Sconv(Fmt *fp) | 968 Sconv(Fmt *fp) |
984 { | 969 { |
985 Sym *s; | 970 Sym *s; |
986 char *pkg, *nam; | |
987 | 971 |
988 s = va_arg(fp->args, Sym*); | 972 s = va_arg(fp->args, Sym*); |
989 if(s == S) { | 973 if(s == S) { |
990 fmtstrcpy(fp, "<S>"); | 974 fmtstrcpy(fp, "<S>"); |
991 return 0; | 975 return 0; |
992 } | 976 } |
| 977 ········ |
| 978 if(fp->flags & FmtShort) |
| 979 goto shrt; |
993 | 980 |
994 » pkg = "<nil>"; | 981 » if(exporting || (fp->flags & FmtSharp)) { |
995 » nam = pkg; | 982 » » if(packagequotes) |
| 983 » » » fmtprint(fp, "\"%Z\"", s->pkg->path); |
| 984 » » else { |
| 985 » » » // PGNS: Should be s->pkg->prefix |
| 986 » » » fmtprint(fp, "%s", s->pkg->name); |
| 987 » » } |
| 988 » » fmtprint(fp, ".%s", s->name); |
| 989 » » return 0; |
| 990 » } |
996 | 991 |
997 » if(s->packagename != nil) | 992 » if(s->pkg != localpkg || (fp->flags & FmtLong)) { |
998 » » pkg = s->packagename; | 993 » » fmtprint(fp, "%s.%s", s->pkg->name, s->name); |
999 » else | 994 » » return 0; |
1000 » » abort(); | 995 » } |
1001 » if(s->name != nil) | 996 |
1002 » » nam = s->name; | 997 shrt: |
| 998 » fmtstrcpy(fp, s->name); |
| 999 » return 0; |
| 1000 |
| 1001 » /* |
1003 | 1002 |
1004 if(!(fp->flags & FmtShort)) { | 1003 if(!(fp->flags & FmtShort)) { |
1005 if((fp->flags & FmtLong) && packagequotes) { | 1004 if((fp->flags & FmtLong) && packagequotes) { |
1006 » » » fmtprint(fp, "\"%s\".%s", s->package, nam); | 1005 » » » fmtprint(fp, "\"%Z\".%s", s->pkg->path, nam); |
1007 return 0; | 1006 return 0; |
1008 } | 1007 } |
1009 if((fp->flags & FmtLong) || strcmp(s->package, package) != 0) { | 1008 if((fp->flags & FmtLong) || strcmp(s->package, package) != 0) { |
1010 fmtprint(fp, "%s.%s", pkg, nam); | 1009 fmtprint(fp, "%s.%s", pkg, nam); |
1011 return 0; | 1010 return 0; |
1012 } | 1011 } |
1013 } | 1012 } |
1014 fmtstrcpy(fp, nam); | 1013 fmtstrcpy(fp, nam); |
| 1014 */ |
1015 return 0; | 1015 return 0; |
1016 } | 1016 } |
1017 | 1017 |
1018 static char* | 1018 static char* |
1019 basicnames[] = | 1019 basicnames[] = |
1020 { | 1020 { |
1021 [TINT] = "int", | 1021 [TINT] = "int", |
1022 [TUINT] = "uint", | 1022 [TUINT] = "uint", |
1023 [TINT8] = "int8", | 1023 [TINT8] = "int8", |
1024 [TUINT8] = "uint8", | 1024 [TUINT8] = "uint8", |
(...skipping 25 matching lines...) Expand all Loading... |
1050 if(t->etype != TFIELD | 1050 if(t->etype != TFIELD |
1051 && t->sym != S | 1051 && t->sym != S |
1052 && !(fp->flags&FmtLong)) { | 1052 && !(fp->flags&FmtLong)) { |
1053 s = t->sym; | 1053 s = t->sym; |
1054 if(t == types[t->etype]) | 1054 if(t == types[t->etype]) |
1055 return fmtprint(fp, "%s", s->name); | 1055 return fmtprint(fp, "%s", s->name); |
1056 if(exporting) { | 1056 if(exporting) { |
1057 if(fp->flags & FmtShort) | 1057 if(fp->flags & FmtShort) |
1058 fmtprint(fp, "%hS", s); | 1058 fmtprint(fp, "%hS", s); |
1059 else | 1059 else |
1060 » » » » fmtprint(fp, "%lS", s); | 1060 » » » » fmtprint(fp, "%S", s); |
1061 » » » if(strcmp(s->package, package) != 0) | 1061 » » » if(s->pkg != localpkg) |
1062 » » » » return 0; | |
1063 » » » if(s->flags & SymImported) | |
1064 return 0; | 1062 return 0; |
1065 if(t->vargen) | 1063 if(t->vargen) |
1066 fmtprint(fp, "·%d", t->vargen); | 1064 fmtprint(fp, "·%d", t->vargen); |
1067 return 0; | 1065 return 0; |
1068 } | 1066 } |
1069 return fmtprint(fp, "%S", s); | 1067 return fmtprint(fp, "%S", s); |
1070 } | 1068 } |
1071 | 1069 |
1072 if(t->etype < nelem(basicnames) && basicnames[t->etype] != nil) { | 1070 if(t->etype < nelem(basicnames) && basicnames[t->etype] != nil) { |
1073 if(isideal(t) && t->etype != TIDEAL && t->etype != TNIL) | 1071 if(isideal(t) && t->etype != TIDEAL && t->etype != TNIL) |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1530 } | 1528 } |
1531 | 1529 |
1532 int | 1530 int |
1533 isselect(Node *n) | 1531 isselect(Node *n) |
1534 { | 1532 { |
1535 Sym *s; | 1533 Sym *s; |
1536 | 1534 |
1537 if(n == N) | 1535 if(n == N) |
1538 return 0; | 1536 return 0; |
1539 n = n->left; | 1537 n = n->left; |
1540 » s = pkglookup("selectsend", "runtime"); | 1538 » s = pkglookup("selectsend", runtimepkg); |
1541 if(s == n->sym) | 1539 if(s == n->sym) |
1542 return 1; | 1540 return 1; |
1543 » s = pkglookup("selectrecv", "runtime"); | 1541 » s = pkglookup("selectrecv", runtimepkg); |
1544 if(s == n->sym) | 1542 if(s == n->sym) |
1545 return 1; | 1543 return 1; |
1546 » s = pkglookup("selectdefault", "runtime"); | 1544 » s = pkglookup("selectdefault", runtimepkg); |
1547 if(s == n->sym) | 1545 if(s == n->sym) |
1548 return 1; | 1546 return 1; |
1549 return 0; | 1547 return 0; |
1550 } | 1548 } |
1551 | 1549 |
1552 int | 1550 int |
1553 isinter(Type *t) | 1551 isinter(Type *t) |
1554 { | 1552 { |
1555 if(t != T) { | 1553 if(t != T) { |
1556 if(t->etype == TINTER) | 1554 if(t->etype == TINTER) |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 } | 1950 } |
1953 return nt; | 1951 return nt; |
1954 } | 1952 } |
1955 | 1953 |
1956 Node* | 1954 Node* |
1957 syslook(char *name, int copy) | 1955 syslook(char *name, int copy) |
1958 { | 1956 { |
1959 Sym *s; | 1957 Sym *s; |
1960 Node *n; | 1958 Node *n; |
1961 | 1959 |
1962 » s = pkglookup(name, "runtime"); | 1960 » s = pkglookup(name, runtimepkg); |
1963 if(s == S || s->def == N) | 1961 if(s == S || s->def == N) |
1964 fatal("looksys: cant find runtime.%s", name); | 1962 fatal("looksys: cant find runtime.%s", name); |
1965 | 1963 |
1966 if(!copy) | 1964 if(!copy) |
1967 return s->def; | 1965 return s->def; |
1968 | 1966 |
1969 n = nod(0, N, N); | 1967 n = nod(0, N, N); |
1970 *n = *s->def; | 1968 *n = *s->def; |
1971 n->type = deep(s->def->type); | 1969 n->type = deep(s->def->type); |
1972 | 1970 |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2578 Symlink *sl; | 2576 Symlink *sl; |
2579 | 2577 |
2580 u = t; | 2578 u = t; |
2581 if(isptr[u->etype]) { | 2579 if(isptr[u->etype]) { |
2582 followptr = 1; | 2580 followptr = 1; |
2583 u = u->type; | 2581 u = u->type; |
2584 } | 2582 } |
2585 | 2583 |
2586 if(u->etype == TINTER) { | 2584 if(u->etype == TINTER) { |
2587 for(f=u->type; f!=T; f=f->down) { | 2585 for(f=u->type; f!=T; f=f->down) { |
2588 » » » if(!exportname(f->sym->name) && strcmp(f->sym->package,
package) != 0) | 2586 » » » if(!exportname(f->sym->name) && f->sym->pkg != localpkg) |
2589 continue; | 2587 continue; |
2590 if(f->sym->flags & SymUniq) | 2588 if(f->sym->flags & SymUniq) |
2591 continue; | 2589 continue; |
2592 f->sym->flags |= SymUniq; | 2590 f->sym->flags |= SymUniq; |
2593 sl = mal(sizeof(*sl)); | 2591 sl = mal(sizeof(*sl)); |
2594 sl->field = f; | 2592 sl->field = f; |
2595 sl->link = slist; | 2593 sl->link = slist; |
2596 sl->followptr = followptr; | 2594 sl->followptr = followptr; |
2597 slist = sl; | 2595 slist = sl; |
2598 } | 2596 } |
2599 return; | 2597 return; |
2600 } | 2598 } |
2601 | 2599 |
2602 u = methtype(t); | 2600 u = methtype(t); |
2603 if(u != T) { | 2601 if(u != T) { |
2604 for(f=u->method; f!=T; f=f->down) { | 2602 for(f=u->method; f!=T; f=f->down) { |
2605 » » » if(!exportname(f->sym->name) && strcmp(f->sym->package,
package) != 0) | 2603 » » » if(!exportname(f->sym->name) && f->sym->pkg != localpkg) |
2606 continue; | 2604 continue; |
2607 if(f->sym->flags & SymUniq) | 2605 if(f->sym->flags & SymUniq) |
2608 continue; | 2606 continue; |
2609 f->sym->flags |= SymUniq; | 2607 f->sym->flags |= SymUniq; |
2610 sl = mal(sizeof(*sl)); | 2608 sl = mal(sizeof(*sl)); |
2611 sl->field = f; | 2609 sl->field = f; |
2612 sl->link = slist; | 2610 sl->link = slist; |
2613 sl->followptr = followptr; | 2611 sl->followptr = followptr; |
2614 slist = sl; | 2612 slist = sl; |
2615 } | 2613 } |
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3372 Sym* | 3370 Sym* |
3373 ngotype(Node *n) | 3371 ngotype(Node *n) |
3374 { | 3372 { |
3375 if(n->sym != S && strncmp(n->sym->name, "autotmp_", 8) != 0) | 3373 if(n->sym != S && strncmp(n->sym->name, "autotmp_", 8) != 0) |
3376 if(n->type->etype != TFUNC || n->type->thistuple == 0) | 3374 if(n->type->etype != TFUNC || n->type->thistuple == 0) |
3377 if(n->type->etype != TSTRUCT || n->type->funarg == 0) | 3375 if(n->type->etype != TSTRUCT || n->type->funarg == 0) |
3378 return typename(n->type)->left->sym; | 3376 return typename(n->type)->left->sym; |
3379 return S; | 3377 return S; |
3380 } | 3378 } |
3381 | 3379 |
3382 char* | 3380 /* |
3383 toimportpath(Strlit *s) | 3381 * Convert raw string to the prefix that will be used in the symbol table. |
| 3382 * Invalid bytes turn into %xx. Right now the only bytes that need |
| 3383 * escaping are %, ., and ", but we escape all control characters too. |
| 3384 */ |
| 3385 static char* |
| 3386 pathtoprefix(char *s) |
3384 { | 3387 { |
3385 » char *p; | 3388 » static char hex[] = "0123456789abcdef"; |
| 3389 » char *p, *r, *w; |
| 3390 » int n; |
3386 | 3391 |
3387 //PGNS: Do better once these are import paths | 3392 » // check for chars that need escaping |
3388 // rather than package names in disguise. | 3393 » n = 0; |
3389 » p = mal(s->len+1); | 3394 » for(r=s; *r; r++) |
3390 » memmove(p, s->s, s->len); | 3395 » » if(*r <= ' ' || *r == '.' || *r == '%' || *r == '"') |
3391 » p[s->len] = '\0'; | 3396 » » » n++; |
| 3397 |
| 3398 » // quick exit |
| 3399 » if(n == 0) |
| 3400 » » return s; |
| 3401 |
| 3402 » // escape |
| 3403 » p = mal((r-s)+1+2*n); |
| 3404 » for(r=s, w=p; *r; r++) { |
| 3405 » » if(*r <= ' ' || *r == '.' || *r == '%' || *r == '"') { |
| 3406 » » » *w++ = '%'; |
| 3407 » » » *w++ = hex[(*r>>4)&0xF]; |
| 3408 » » » *w++ = hex[*r&0xF]; |
| 3409 » » } else |
| 3410 » » » *w++ = *r; |
| 3411 » } |
| 3412 » *w = '\0'; |
3392 return p; | 3413 return p; |
3393 } | 3414 } |
| 3415 |
| 3416 static Pkg *phash[128]; |
| 3417 |
| 3418 Pkg* |
| 3419 mkpkg(Strlit *path) |
| 3420 { |
| 3421 Pkg *p; |
| 3422 int h; |
| 3423 ········ |
| 3424 if(strlen(path->s) != path->len) |
| 3425 fatal("import path contains NUL byte"); |
| 3426 ········ |
| 3427 h = stringhash(path->s) & (nelem(phash)-1); |
| 3428 for(p=phash[h]; p; p=p->link) |
| 3429 if(p->path->len == path->len && memcmp(path->s, p->path->s, path
->len) == 0) |
| 3430 return p; |
| 3431 |
| 3432 p = mal(sizeof *p); |
| 3433 p->path = path; |
| 3434 p->prefix = pathtoprefix(path->s); |
| 3435 p->link = phash[h]; |
| 3436 phash[h] = p; |
| 3437 return p; |
| 3438 } |
| 3439 |
| 3440 Strlit* |
| 3441 strlit(char *s) |
| 3442 { |
| 3443 Strlit *t; |
| 3444 ········ |
| 3445 t = mal(sizeof *t + strlen(s)); |
| 3446 strcpy(t->s, s); |
| 3447 t->len = strlen(s); |
| 3448 return t; |
| 3449 } |
| 3450 |
OLD | NEW |