diff options
author | Russ Cox <rsc@golang.org> | 2020-04-01 15:51:08 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2020-04-21 16:47:01 +0000 |
commit | 768201729df89a28aae2cc5e41a33ffcb759c113 (patch) | |
tree | 212e9376ed8948f04fb2bedaa712313396ac149a /src/cmd/compile/internal/syntax/nodes.go | |
parent | 4f27e1d7aadba639cceaa93f77ec0c7ee3fee01b (diff) | |
download | go-768201729df89a28aae2cc5e41a33ffcb759c113.tar.gz go-768201729df89a28aae2cc5e41a33ffcb759c113.zip |
cmd/compile: detect and diagnose invalid //go: directive placement
Thie CL changes cmd/compile/internal/syntax to give the gc half of
the compiler more control over pragma handling, so that it can prepare
better errors, diagnose misuse, and so on. Before, the API between
the two was hard-coded as a uint16. Now it is an interface{}.
This should set us up better for future directives.
In addition to the split, this CL emits a "misplaced compiler directive"
error for any directive that is in a place where it has no effect.
I've certainly been confused in the past by adding comments
that were doing nothing and not realizing it. This should help
avoid that kind of confusion.
The rule, now applied consistently, is that a //go: directive
must appear on a line by itself immediately before the declaration
specifier it means to apply to. See cmd/compile/doc.go for
precise text and test/directive.go for examples.
This may cause some code to stop compiling, but that code
was broken. For example, this code formerly applied the
//go:noinline to f (not c) but now will fail to compile:
//go:noinline
const c = 1
func f() {}
Change-Id: Ieba9b8d90a27cfab25de79d2790a895cefe5296f
Reviewed-on: https://go-review.googlesource.com/c/go/+/228578
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/syntax/nodes.go')
-rw-r--r-- | src/cmd/compile/internal/syntax/nodes.go | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/src/cmd/compile/internal/syntax/nodes.go b/src/cmd/compile/internal/syntax/nodes.go index 9a74c0250b..815630fcd4 100644 --- a/src/cmd/compile/internal/syntax/nodes.go +++ b/src/cmd/compile/internal/syntax/nodes.go @@ -34,6 +34,7 @@ func (*node) aNode() {} // package PkgName; DeclList[0], DeclList[1], ... type File struct { + Pragma Pragma PkgName *Name DeclList []Decl Lines uint @@ -52,9 +53,10 @@ type ( // Path // LocalPkgName Path ImportDecl struct { + Group *Group // nil means not part of a group + Pragma Pragma LocalPkgName *Name // including "."; nil means no rename present Path *BasicLit - Group *Group // nil means not part of a group decl } @@ -62,20 +64,21 @@ type ( // NameList = Values // NameList Type = Values ConstDecl struct { - NameList []*Name - Type Expr // nil means no type - Values Expr // nil means no values Group *Group // nil means not part of a group + Pragma Pragma + NameList []*Name + Type Expr // nil means no type + Values Expr // nil means no values decl } // Name Type TypeDecl struct { + Group *Group // nil means not part of a group + Pragma Pragma Name *Name Alias bool Type Expr - Group *Group // nil means not part of a group - Pragma Pragma decl } @@ -83,10 +86,11 @@ type ( // NameList Type = Values // NameList = Values VarDecl struct { - NameList []*Name - Type Expr // nil means no type - Values Expr // nil means no values Group *Group // nil means not part of a group + Pragma Pragma + NameList []*Name + Type Expr // nil means no type + Values Expr // nil means no values decl } @@ -95,12 +99,11 @@ type ( // func Receiver Name Type { Body } // func Receiver Name Type FuncDecl struct { - Attr map[string]bool // go:attr map - Recv *Field // nil means regular function + Pragma Pragma + Recv *Field // nil means regular function Name *Name Type *FuncType Body *BlockStmt // nil means no body (forward declaration) - Pragma Pragma // TODO(mdempsky): Cleaner solution. decl } ) |