github.com/axw/llgo@v0.0.0-20160805011314-95b5fe4dca20/irgen/annotations.go (about)

     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"
    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"
    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  }