aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-06-29 15:13:37 -0700
committerRuss Cox <rsc@golang.org>2009-06-29 15:13:37 -0700
commit9435dc2bdfa595562655de56c77cf6f4eb103d75 (patch)
tree7a8cd4536a42fb7aedffa342de2bb6cd79e58595 /src/cmd/ld
parent3119221ed83878b45b488e5b9c5dc0a883c79414 (diff)
downloadgo-9435dc2bdfa595562655de56c77cf6f4eb103d75.tar.xz
allow forward declaration of struct in another file
(in the same package). allow forward method declaration to be satisfied by implementation in another file (in the same package). all methods must be declared in the same file as the receiver type. R=ken OCL=30864 CL=30869
Diffstat (limited to 'src/cmd/ld')
-rw-r--r--src/cmd/ld/go.c74
1 files changed, 39 insertions, 35 deletions
diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c
index 6990d73292..54a8e48d1d 100644
--- a/src/cmd/ld/go.c
+++ b/src/cmd/ld/go.c
@@ -22,7 +22,6 @@ typedef struct Import Import;
struct Import
{
Import *hash; // next in hash table
- int export; // marked as export?
char *prefix; // "type", "var", "func", "const"
char *name;
char *def;
@@ -89,7 +88,7 @@ gotypefor(char *name)
static void loadpkgdata(char*, char*, int);
static int parsemethod(char**, char*, char**);
-static int parsepkgdata(char*, char**, char*, int*, char**, char**, char**);
+static int parsepkgdata(char*, char**, char*, char**, char**, char**);
void
ldpkg(Biobuf *f, int64 len, char *filename)
@@ -154,47 +153,63 @@ ldpkg(Biobuf *f, int64 len, char *filename)
loadpkgdata(filename, p0, p1 - p0);
}
+/*
+ * a and b don't match.
+ * is one a forward declaration and the other a valid completion?
+ * if so, return the one to keep.
+ */
+char*
+forwardfix(char *a, char *b)
+{
+ char *t;
+
+ if(strlen(a) > strlen(b)) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ if(strcmp(a, "struct") == 0 && strncmp(b, "struct ", 7) == 0)
+ return b;
+ if(strcmp(a, "interface") == 0 && strncmp(b, "interface ", 10) == 0)
+ return b;
+ return nil;
+}
+
static void
loadpkgdata(char *file, char *data, int len)
{
- int export;
- char *p, *ep, *prefix, *name, *def;
+ char *p, *ep, *prefix, *name, *def, *ndef;
Import *x;
file = strdup(file);
p = data;
ep = data + len;
- while(parsepkgdata(file, &p, ep, &export, &prefix, &name, &def) > 0) {
+ while(parsepkgdata(file, &p, ep, &prefix, &name, &def) > 0) {
x = ilookup(name);
if(x->prefix == nil) {
x->prefix = prefix;
x->def = def;
x->file = file;
- x->export = export;
+ } else if(strcmp(x->prefix, prefix) != 0) {
+ fprint(2, "%s: conflicting definitions for %s\n", argv0, name);
+ fprint(2, "%s:\t%s %s ...\n", x->file, x->prefix, name);
+ fprint(2, "%s:\t%s %s ...\n", file, prefix, name);
+ nerrors++;
+ } else if(strcmp(x->def, def) == 0) {
+ // fine
+ } else if((ndef = forwardfix(x->def, def)) != nil) {
+ x->def = ndef;
} else {
- if(strcmp(x->prefix, prefix) != 0) {
- fprint(2, "%s: conflicting definitions for %s\n", argv0, name);
- fprint(2, "%s:\t%s %s ...\n", x->file, x->prefix, name);
- fprint(2, "%s:\t%s %s ...\n", file, prefix, name);
- nerrors++;
- }
- else if(strcmp(x->def, def) != 0) {
- fprint(2, "%s: conflicting definitions for %s\n", argv0, name);
- fprint(2, "%s:\t%s %s %s\n", x->file, x->prefix, name, x->def);
- fprint(2, "%s:\t%s %s %s\n", file, prefix, name, def);
- nerrors++;
- }
-
- // okay if some .6 say export and others don't.
- // all it takes is one.
- if(export)
- x->export = 1;
+ fprint(2, "%d: conflicting definitions for %s\n", argv0, name);
+ fprint(2, "%s:\t%s %s %s\n", x->file, x->prefix, name, x->def);
+ fprint(2, "%s:\t%s %s %s\n", file, prefix, name, def);
+ nerrors++;
}
}
}
static int
-parsepkgdata(char *file, char **pp, char *ep, int *exportp, char **prefixp, char **namep, char **defp)
+parsepkgdata(char *file, char **pp, char *ep, char **prefixp, char **namep, char **defp)
{
char *p, *prefix, *name, *def, *edef, *meth;
int n;
@@ -206,17 +221,6 @@ parsepkgdata(char *file, char **pp, char *ep, int *exportp, char **prefixp, char
if(p == ep || strncmp(p, "$$\n", 3) == 0)
return 0;
- // [export|package ]
- *exportp = 0;
- if(p + 7 <= ep && strncmp(p, "export ", 7) == 0) {
- *exportp = 1;
- p += 7;
- }
- else if(p + 8 <= ep && strncmp(p, "package ", 8) == 0) {
- *exportp = 2;
- p += 8;
- }
-
// prefix: (var|type|func|const)
prefix = p;