Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
66bb399f
Commit
66bb399f
authored
Aug 12, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
whole-package compilation
R=ken OCL=33063 CL=33095
parent
866b2723
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
187 additions
and
66 deletions
+187
-66
dcl.c
src/cmd/gc/dcl.c
+1
-8
export.c
src/cmd/gc/export.c
+10
-0
go.h
src/cmd/gc/go.h
+2
-0
go.y
src/cmd/gc/go.y
+12
-32
init.c
src/cmd/gc/init.c
+11
-7
lex.c
src/cmd/gc/lex.c
+78
-18
sinit.c
src/cmd/gc/sinit.c
+73
-1
No files found.
src/cmd/gc/dcl.c
View file @
66bb399f
...
...
@@ -649,16 +649,9 @@ funchdr(Node *n)
Node
*
nt
;
if
(
n
->
nname
!=
N
)
{
// TODO(rsc): remove once forward declarations are gone
if
(
n
->
nname
->
sym
->
def
&&
n
->
nname
->
sym
->
def
->
class
==
PFUNC
)
{
nt
=
n
->
nname
->
ntype
;
n
->
nname
=
n
->
nname
->
sym
->
def
;
n
->
nname
->
ntype
=
nt
;
n
->
nname
->
type
=
T
;
}
else
{
n
->
nname
->
op
=
ONAME
;
declare
(
n
->
nname
,
PFUNC
);
}
n
->
nname
->
defn
=
n
;
}
// change the declaration context from extern to auto
...
...
src/cmd/gc/export.c
View file @
66bb399f
...
...
@@ -299,6 +299,8 @@ pkgtype(Sym *s)
t
->
sym
=
s
;
s
->
def
=
typenod
(
t
);
}
if
(
s
->
def
->
type
==
T
)
yyerror
(
"pkgtype %lS"
,
s
);
return
s
->
def
->
type
;
}
...
...
@@ -314,6 +316,8 @@ mypackage(Sym *s)
void
importconst
(
Sym
*
s
,
Type
*
t
,
Node
*
n
)
{
Node
*
n1
;
if
(
!
exportname
(
s
->
name
)
&&
!
mypackage
(
s
))
return
;
importsym
(
s
,
OLITERAL
);
...
...
@@ -327,6 +331,11 @@ importconst(Sym *s, Type *t, Node *n)
yyerror
(
"expression must be a constant"
);
return
;
}
if
(
n
->
sym
!=
S
)
{
n1
=
nod
(
OXXX
,
N
,
N
);
*
n1
=
*
n
;
n
=
n1
;
}
n
->
sym
=
s
;
declare
(
n
,
PEXTERN
);
...
...
@@ -360,6 +369,7 @@ importvar(Sym *s, Type *t, int ctxt)
void
importtype
(
Type
*
pt
,
Type
*
t
)
{
if
(
pt
!=
T
&&
t
!=
T
)
typedcl2
(
pt
,
t
);
if
(
debug
[
'E'
])
...
...
src/cmd/gc/go.h
View file @
66bb399f
...
...
@@ -198,6 +198,7 @@ struct Node
uchar
walkdef
;
uchar
typecheck
;
uchar
local
;
uchar
initorder
;
// most nodes
Node
*
left
;
...
...
@@ -649,6 +650,7 @@ EXTERN Mpint* maxintval[NTYPE];
EXTERN
Mpflt
*
minfltval
[
NTYPE
];
EXTERN
Mpflt
*
maxfltval
[
NTYPE
];
EXTERN
NodeList
*
xtop
;
EXTERN
NodeList
*
externdcl
;
EXTERN
NodeList
*
closures
;
EXTERN
NodeList
*
exportlist
;
...
...
src/cmd/gc/go.y
View file @
66bb399f
...
...
@@ -120,29 +120,7 @@ file:
imports
xdcl_list
{
NodeList *l;
if(nsyntaxerrors == 0)
testdclstack();
typecheckok = 1;
if(debug['
f
'])
frame(1);
defercheckwidth();
typechecklist($4, Etop);
resumecheckwidth();
for(l=$4; l; l=l->next)
if(l->n->op == ODCLFUNC)
funccompile(l->n);
if(nerrors == 0)
fninit($4);
while(closures) {
l = closures;
closures = nil;
for(; l; l=l->next)
funccompile(l->n);
}
dclchecks();
xtop = concat(xtop, $4);
}
package:
...
...
@@ -262,15 +240,17 @@ import_done:
if(my == import && strcmp(import->name, package) == 0)
break;
if(my->def != N) {
// TODO(rsc): this line is only needed because of the
// package net
// import "net"
// convention; if we get rid of it, the check can go away
// and we can just always print the error
if(my->def->op != OPACK || strcmp(my->name, import->name) != 0)
yyerror("redeclaration of %S by import", my);
}
// TODO(rsc): this line is needed for a package
// which does bytes := in a function, which creates
// an ONONAME for bytes, but then a different file
// imports "bytes". more generally we need to figure out
// what it means if one file imports "bytes" and another
// declares a top-level name.
if(my->def && my->def->op == ONONAME)
my->def = N;
if(my->def)
yyerror("redeclaration of %S by import\n\t%N", my, my->def);
my->def = nod(OPACK, N, N);
my->def->sym = import;
import->block = -1; // above top level
...
...
src/cmd/gc/init.c
View file @
66bb399f
...
...
@@ -15,6 +15,7 @@ Node*
renameinit
(
Node
*
n
)
{
Sym
*
s
;
static
int
initgen
;
s
=
n
->
sym
;
if
(
s
==
S
)
...
...
@@ -22,7 +23,7 @@ renameinit(Node *n)
if
(
strcmp
(
s
->
name
,
"init"
)
!=
0
)
return
n
;
snprint
(
namebuf
,
sizeof
(
namebuf
),
"init·%
s"
,
filename
);
snprint
(
namebuf
,
sizeof
(
namebuf
),
"init·%
d"
,
++
initgen
);
s
=
lookup
(
namebuf
);
return
newname
(
s
);
}
...
...
@@ -70,7 +71,7 @@ anyinit(NodeList *n)
return
1
;
// is there an explicit init function
snprint
(
namebuf
,
sizeof
(
namebuf
),
"init·
%s"
,
filename
);
snprint
(
namebuf
,
sizeof
(
namebuf
),
"init·
1"
);
s
=
lookup
(
namebuf
);
if
(
s
->
def
!=
N
)
return
1
;
...
...
@@ -92,6 +93,7 @@ anyinit(NodeList *n)
void
fninit
(
NodeList
*
n
)
{
int
i
;
Node
*
gatevar
;
Node
*
a
,
*
b
,
*
fn
;
NodeList
*
r
;
...
...
@@ -110,7 +112,7 @@ fninit(NodeList *n)
r
=
nil
;
// (1)
snprint
(
namebuf
,
sizeof
(
namebuf
),
"initdone·
%s"
,
filename
);
snprint
(
namebuf
,
sizeof
(
namebuf
),
"initdone·
"
);
gatevar
=
newname
(
lookup
(
namebuf
));
addvar
(
gatevar
,
types
[
TUINT8
],
PEXTERN
);
...
...
@@ -118,7 +120,7 @@ fninit(NodeList *n)
maxarg
=
0
;
snprint
(
namebuf
,
sizeof
(
namebuf
),
"Init·
%s"
,
filename
);
snprint
(
namebuf
,
sizeof
(
namebuf
),
"Init·
"
);
// this is a botch since we need a known name to
// call the top level init function out of rt0
...
...
@@ -168,13 +170,15 @@ fninit(NodeList *n)
}
// (8)
r
=
concat
(
r
,
initfix
(
n
)
);
r
=
concat
(
r
,
n
);
// (9)
// could check that it is fn of no args/returns
snprint
(
namebuf
,
sizeof
(
namebuf
),
"init·%s"
,
filename
);
for
(
i
=
1
;;
i
++
)
{
snprint
(
namebuf
,
sizeof
(
namebuf
),
"init·%d"
,
i
);
s
=
lookup
(
namebuf
);
if
(
s
->
def
!=
N
)
{
if
(
s
->
def
==
N
)
break
;
a
=
nod
(
OCALL
,
s
->
def
,
N
);
r
=
list
(
r
,
a
);
}
...
...
src/cmd/gc/lex.c
View file @
66bb399f
...
...
@@ -10,6 +10,7 @@
extern
int
yychar
;
Sym
*
anysym
;
char
nopackage
[]
=
"____"
;
#define DBG if(!debug['x']);else print
enum
...
...
@@ -20,10 +21,11 @@ enum
int
main
(
int
argc
,
char
*
argv
[])
{
int
c
;
int
i
,
c
;
NodeList
*
l
;
outfile
=
nil
;
package
=
"____"
;
package
=
nopackage
;
ARGBEGIN
{
default:
c
=
ARGC
();
...
...
@@ -44,7 +46,7 @@ main(int argc, char *argv[])
break
;
}
ARGEND
if
(
argc
!=
1
)
if
(
argc
<
1
)
goto
usage
;
pathname
=
mal
(
100
);
...
...
@@ -69,31 +71,57 @@ main(int argc, char *argv[])
lexinit
();
typeinit
();
lineno
=
1
;
block
=
1
;
blockgen
=
1
;
dclcontext
=
PEXTERN
;
nerrors
=
0
;
lineno
=
1
;
setfilename
(
argv
[
0
]);
infile
=
argv
[
0
];
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
if
(
i
==
0
)
setfilename
(
argv
[
i
]);
infile
=
argv
[
i
];
linehist
(
infile
,
0
,
0
);
curio
.
infile
=
infile
;
curio
.
bin
=
Bopen
(
infile
,
OREAD
);
if
(
curio
.
bin
==
nil
)
fatal
(
"cant open: %s
"
,
infile
);
fatal
(
"open%s: %r
"
,
infile
);
curio
.
peekc
=
0
;
curio
.
peekc1
=
0
;
dclcontext
=
PEXTERN
;
block
=
1
;
nerrors
=
0
;
yyparse
();
runifacechecks
();
if
(
nsyntaxerrors
!=
0
)
errorexit
();
linehist
(
nil
,
0
,
0
);
if
(
curio
.
bin
!=
nil
)
Bterm
(
curio
.
bin
);
}
testdclstack
();
typecheckok
=
1
;
if
(
debug
[
'f'
])
frame
(
1
);
defercheckwidth
();
typechecklist
(
xtop
,
Etop
);
resumecheckwidth
();
for
(
l
=
xtop
;
l
;
l
=
l
->
next
)
if
(
l
->
n
->
op
==
ODCLFUNC
)
funccompile
(
l
->
n
);
if
(
nerrors
==
0
)
fninit
(
xtop
);
while
(
closures
)
{
l
=
closures
;
closures
=
nil
;
for
(;
l
;
l
=
l
->
next
)
funccompile
(
l
->
n
);
}
dclchecks
();
runifacechecks
();
if
(
nerrors
)
errorexit
();
...
...
@@ -264,6 +292,8 @@ importfile(Val *f)
int32
c
;
int
len
;
// TODO: don't bother reloading imports more than once
if
(
f
->
ctype
!=
CTSTR
)
{
yyerror
(
"import statement not a string"
);
return
;
...
...
@@ -1427,6 +1457,16 @@ lexname(int lex)
return
buf
;
}
int
specialsym
(
Sym
*
s
)
{
if
(
strcmp
(
s
->
name
,
"byte"
)
==
0
&&
s
->
def
->
sym
==
lookup
(
"uint8"
))
return
1
;
if
(
strcmp
(
s
->
name
,
"iota"
)
==
0
&&
s
->
def
->
sym
==
S
)
return
1
;
return
0
;
}
void
mkpackage
(
char
*
pkg
)
{
...
...
@@ -1434,23 +1474,43 @@ mkpackage(char* pkg)
int32
h
;
char
*
p
;
if
(
bout
!=
nil
)
{
yyerror
(
"mkpackage: called again %s %s"
,
pkg
,
package
);
return
;
}
// redefine all names to be this package
if
(
package
==
nopackage
)
{
// redefine all names to be this package.
for
(
h
=
0
;
h
<
NHASH
;
h
++
)
for
(
s
=
hash
[
h
];
s
!=
S
;
s
=
s
->
link
)
if
(
s
->
package
==
package
)
if
(
s
->
package
==
no
package
)
s
->
package
=
pkg
;
package
=
pkg
;
}
else
{
if
(
strcmp
(
pkg
,
package
)
!=
0
)
yyerror
(
"package %s; expected %s"
,
pkg
,
package
);
for
(
h
=
0
;
h
<
NHASH
;
h
++
)
{
for
(
s
=
hash
[
h
];
s
!=
S
;
s
=
s
->
link
)
{
if
(
s
->
def
==
N
||
s
->
package
!=
package
)
continue
;
if
(
s
->
def
->
op
==
OPACK
)
{
// throw away top-level package name leftover
// from previous file.
s
->
def
=
N
;
continue
;
}
if
(
s
->
def
->
sym
!=
s
&&
!
specialsym
(
s
))
{
// throw away top-level name left over
// from previous import . "x"
s
->
def
=
N
;
continue
;
}
}
}
}
/*
// declare this name as a package
s = lookup(package);
s->def = nod(OPACK, N, N);
s->def->sym = s;
s->block = -1; // above top level
*/
if
(
outfile
==
nil
)
{
p
=
strrchr
(
infile
,
'/'
);
...
...
src/cmd/gc/sinit.c
View file @
66bb399f
...
...
@@ -457,13 +457,85 @@ return;
}
static
void
init1
(
Node
*
n
,
NodeList
**
out
)
{
NodeList
*
l
;
if
(
n
==
N
)
return
;
init1
(
n
->
left
,
out
);
init1
(
n
->
right
,
out
);
for
(
l
=
n
->
list
;
l
;
l
=
l
->
next
)
init1
(
l
->
n
,
out
);
if
(
n
->
op
!=
ONAME
)
return
;
switch
(
n
->
class
)
{
case
PEXTERN
:
case
PFUNC
:
break
;
default:
return
;
}
if
(
n
->
initorder
==
1
)
return
;
if
(
n
->
initorder
==
2
)
fatal
(
"init loop"
);
// make sure that everything n depends on is initialized.
// n->defn is an assignment to n
n
->
initorder
=
2
;
if
(
n
->
defn
!=
N
)
{
switch
(
n
->
defn
->
op
)
{
case
ODCLFUNC
:
for
(
l
=
n
->
defn
->
nbody
;
l
;
l
=
l
->
next
)
init1
(
l
->
n
,
out
);
break
;
case
OAS
:
if
(
n
->
defn
->
left
!=
n
)
{
default:
dump
(
"defn"
,
n
->
defn
);
fatal
(
"bad defn"
);
}
init1
(
n
->
defn
->
right
,
out
);
if
(
debug
[
'j'
])
print
(
"%S
\n
"
,
n
->
sym
);
*
out
=
list
(
*
out
,
n
->
defn
);
break
;
}
}
n
->
initorder
=
1
;
return
;
}
static
void
initreorder
(
NodeList
*
l
,
NodeList
**
out
)
{
Node
*
n
;
for
(;
l
;
l
=
l
->
next
)
{
n
=
l
->
n
;
switch
(
n
->
op
)
{
case
ODCLFUNC
:
case
ODCLCONST
:
case
ODCLTYPE
:
continue
;
}
initreorder
(
n
->
ninit
,
out
);
n
->
ninit
=
nil
;
init1
(
n
,
out
);
}
}
NodeList
*
initfix
(
NodeList
*
l
)
{
Node
*
r
;
xxx
.
list
=
nil
;
init
lin
(
l
);
init
reorder
(
l
,
&
xxx
.
list
);
if
(
0
)
return
xxx
.
list
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment