Peter Collingbourne | ad9841e | 2014-11-27 00:06:42 +0000 | [diff] [blame] | 1 | //===- annotations.go - annotation processor ------------------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file converts llgo annotations into attributes. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | package irgen |
| 15 | |
| 16 | import ( |
| 17 | "go/ast" |
| 18 | "go/token" |
Peter Collingbourne | 56109b7 | 2015-01-13 20:45:08 +0000 | [diff] [blame] | 19 | "llvm.org/llgo/third_party/gotools/go/loader" |
| 20 | "llvm.org/llgo/third_party/gotools/go/ssa" |
| 21 | "llvm.org/llgo/third_party/gotools/go/types" |
Peter Collingbourne | ad9841e | 2014-11-27 00:06:42 +0000 | [diff] [blame] | 22 | "llvm.org/llvm/bindings/go/llvm" |
| 23 | ) |
| 24 | |
| 25 | // processAnnotations takes an *ssa.Package and a |
| 26 | // *importer.PackageInfo, and processes all of the |
| 27 | // llgo source annotations attached to each top-level |
| 28 | // function and global variable. |
| 29 | func (c *compiler) processAnnotations(u *unit, pkginfo *loader.PackageInfo) { |
| 30 | members := make(map[types.Object]llvm.Value, len(u.globals)) |
| 31 | for k, v := range u.globals { |
| 32 | members[k.(ssa.Member).Object()] = v |
| 33 | } |
| 34 | applyAttributes := func(attrs []Attribute, idents ...*ast.Ident) { |
| 35 | if len(attrs) == 0 { |
| 36 | return |
| 37 | } |
| 38 | for _, ident := range idents { |
| 39 | if v := members[pkginfo.ObjectOf(ident)]; !v.IsNil() { |
| 40 | for _, attr := range attrs { |
| 41 | attr.Apply(v) |
| 42 | } |
| 43 | } |
| 44 | } |
| 45 | } |
| 46 | for _, f := range pkginfo.Files { |
| 47 | for _, decl := range f.Decls { |
| 48 | switch decl := decl.(type) { |
| 49 | case *ast.FuncDecl: |
| 50 | attrs := parseAttributes(decl.Doc) |
| 51 | applyAttributes(attrs, decl.Name) |
| 52 | case *ast.GenDecl: |
| 53 | if decl.Tok != token.VAR { |
| 54 | continue |
| 55 | } |
| 56 | for _, spec := range decl.Specs { |
| 57 | varspec := spec.(*ast.ValueSpec) |
| 58 | attrs := parseAttributes(decl.Doc) |
| 59 | applyAttributes(attrs, varspec.Names...) |
| 60 | } |
| 61 | } |
| 62 | } |
| 63 | } |
| 64 | } |