Permalink
Switch branches/tags
weekly.2012-03-27 weekly.2012-03-22 weekly.2012-03-13 weekly.2012-03-04 weekly.2012-02-22 weekly.2012-02-14 weekly.2012-02-07 weekly.2012-01-27 weekly.2012-01-20 weekly.2012-01-15 weekly.2011-12-22 weekly.2011-12-14 weekly.2011-12-06 weekly.2011-12-02 weekly.2011-12-01 weekly.2011-11-18 weekly.2011-11-09 weekly.2011-11-08 weekly.2011-11-02 weekly.2011-11-01 weekly.2011-10-26 weekly.2011-10-25 weekly.2011-10-18 weekly.2011-10-06 weekly.2011-09-21 weekly.2011-09-16 weekly.2011-09-07 weekly.2011-09-01 weekly.2011-08-17 weekly.2011-08-10 weekly.2011-07-29 weekly.2011-07-19 weekly.2011-07-07 weekly.2011-06-23 weekly.2011-06-16 weekly.2011-06-09 weekly.2011-06-02 weekly.2011-05-22 weekly.2011-04-27 weekly.2011-04-13 weekly.2011-04-04 weekly.2011-03-28 weekly.2011-03-15 weekly.2011-03-07.1 weekly.2011-03-07 weekly.2011-02-24 weekly.2011-02-15 weekly.2011-02-01.1 weekly.2011-02-01 weekly.2011-01-20 weekly.2011-01-19 weekly.2011-01-12 weekly.2011-01-06 weekly.2010-12-22 weekly.2010-12-15.1 weekly.2010-12-15 weekly.2010-12-08 weekly.2010-12-02 weekly.2010-11-23 weekly.2010-11-10 weekly.2010-11-02 weekly.2010-10-27 weekly.2010-10-20 weekly.2010-10-13.1 weekly.2010-10-13 weekly.2010-09-29 weekly.2010-09-22 weekly.2010-09-15 weekly.2010-09-06 weekly.2010-08-25 weekly.2010-08-11 weekly.2010-08-04 weekly.2010-07-29 weekly.2010-07-14 weekly.2010-07-01 weekly.2010-06-21 weekly.2010-06-09 weekly.2010-05-27 weekly.2010-05-04 weekly.2010-04-27 weekly.2010-04-13 weekly.2010-03-30 weekly.2010-03-22 weekly.2010-03-15 weekly.2010-03-04 weekly.2010-02-23 weekly.2010-02-17 weekly.2010-02-04 weekly.2010-01-27 weekly.2010-01-13 weekly.2010-01-05 weekly.2009-12-22 weekly.2009-12-09 weekly.2009-12-07 weekly.2009-11-17 weekly.2009-11-12 weekly.2009-11-10.1 weekly.2009-11-10 weekly.2009-11-06 weekly
Nothing to show
Find file Copy path
189 lines (174 sloc) 5.34 KB
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
import (
"cmd/compile/internal/syntax"
"cmd/internal/objabi"
"cmd/internal/src"
"fmt"
"strings"
)
// lineno is the source position at the start of the most recently lexed token.
// TODO(gri) rename and eventually remove
var lineno src.XPos
func makePos(base *src.PosBase, line, col uint) src.XPos {
return Ctxt.PosTable.XPos(src.MakePos(base, line, col))
}
func isSpace(c rune) bool {
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
}
func isQuoted(s string) bool {
return len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"'
}
const (
// Func pragmas.
Nointerface syntax.Pragma = 1 << iota
Noescape // func parameters don't escape
Norace // func must not have race detector annotations
Nosplit // func should not execute on separate stack
Noinline // func should not be inlined
CgoUnsafeArgs // treat a pointer to one arg as a pointer to them all
UintptrEscapes // pointers converted to uintptr escape
// Runtime-only func pragmas.
// See ../../../../runtime/README.md for detailed descriptions.
Systemstack // func must run on system stack
Nowritebarrier // emit compiler error instead of write barrier
Nowritebarrierrec // error on write barrier in this or recursive callees
Yeswritebarrierrec // cancels Nowritebarrierrec in this function and callees
// Runtime-only type pragmas
NotInHeap // values of this type must not be heap allocated
)
func pragmaValue(verb string) syntax.Pragma {
switch verb {
case "go:nointerface":
if objabi.Fieldtrack_enabled != 0 {
return Nointerface
}
case "go:noescape":
return Noescape
case "go:norace":
return Norace
case "go:nosplit":
return Nosplit
case "go:noinline":
return Noinline
case "go:systemstack":
return Systemstack
case "go:nowritebarrier":
return Nowritebarrier
case "go:nowritebarrierrec":
return Nowritebarrierrec | Nowritebarrier // implies Nowritebarrier
case "go:yeswritebarrierrec":
return Yeswritebarrierrec
case "go:cgo_unsafe_args":
return CgoUnsafeArgs
case "go:uintptrescapes":
// For the next function declared in the file
// any uintptr arguments may be pointer values
// converted to uintptr. This directive
// ensures that the referenced allocated
// object, if any, is retained and not moved
// until the call completes, even though from
// the types alone it would appear that the
// object is no longer needed during the
// call. The conversion to uintptr must appear
// in the argument list.
// Used in syscall/dll_windows.go.
return UintptrEscapes
case "go:notinheap":
return NotInHeap
}
return 0
}
// pragcgo is called concurrently if files are parsed concurrently.
func (p *noder) pragcgo(pos syntax.Pos, text string) {
f := pragmaFields(text)
verb := strings.TrimPrefix(f[0], "go:")
f[0] = verb
switch verb {
case "cgo_export_static", "cgo_export_dynamic":
switch {
case len(f) == 2 && !isQuoted(f[1]):
case len(f) == 3 && !isQuoted(f[1]) && !isQuoted(f[2]):
default:
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf(`usage: //go:%s local [remote]`, verb)})
return
}
case "cgo_import_dynamic":
switch {
case len(f) == 2 && !isQuoted(f[1]):
case len(f) == 3 && !isQuoted(f[1]) && !isQuoted(f[2]):
case len(f) == 4 && !isQuoted(f[1]) && !isQuoted(f[2]) && isQuoted(f[3]):
f[3] = strings.Trim(f[3], `"`)
default:
p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["library"]]`})
return
}
case "cgo_import_static":
switch {
case len(f) == 2 && !isQuoted(f[1]):
default:
p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_static local`})
return
}
case "cgo_dynamic_linker":
switch {
case len(f) == 2 && isQuoted(f[1]):
f[1] = strings.Trim(f[1], `"`)
default:
p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_dynamic_linker "path"`})
return
}
case "cgo_ldflag":
switch {
case len(f) == 2 && isQuoted(f[1]):
f[1] = strings.Trim(f[1], `"`)
default:
p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_ldflag "arg"`})
return
}
default:
return
}
p.pragcgobuf = append(p.pragcgobuf, f)
}
// pragmaFields is similar to strings.FieldsFunc(s, isSpace)
// but does not split when inside double quoted regions and always
// splits before the start and after the end of a double quoted region.
// pragmaFields does not recognize escaped quotes. If a quote in s is not
// closed the part after the opening quote will not be returned as a field.
func pragmaFields(s string) []string {
var a []string
inQuote := false
fieldStart := -1 // Set to -1 when looking for start of field.
for i, c := range s {
switch {
case c == '"':
if inQuote {
inQuote = false
a = append(a, s[fieldStart:i+1])
fieldStart = -1
} else {
inQuote = true
if fieldStart >= 0 {
a = append(a, s[fieldStart:i])
}
fieldStart = i
}
case !inQuote && isSpace(c):
if fieldStart >= 0 {
a = append(a, s[fieldStart:i])
fieldStart = -1
}
default:
if fieldStart == -1 {
fieldStart = i
}
}
}
if !inQuote && fieldStart >= 0 { // Last field might end at the end of the string.
a = append(a, s[fieldStart:])
}
return a
}