func (v *AttributeCheck) CheckFunctionDecl(s *SemanticAnalyzer, n *parser.FunctionDecl) { v.CheckAttrsDistanceFromLine(s, n.Function.Type.Attrs(), n.Pos().Line, "function", n.Function.Name) for _, attr := range n.Function.Type.Attrs() { switch attr.Key { case "deprecated": case "unused": case "c": default: s.Err(attr, "Invalid function attribute key `%s`", attr.Key) } } }
func (v *Codegen) declareFunctionDecl(n *parser.FunctionDecl) { mangledName := n.Function.MangledName(parser.MANGLE_ARK_UNSTABLE) function := v.curFile.LlvmModule.NamedFunction(mangledName) if !function.IsNil() { v.err("function `%s` already exists in module", n.Function.Name) } else { /*numOfParams := len(n.Function.Parameters) if n.Function.Type.Receiver != nil { numOfParams++ }*/ // find them attributes yo attrs := n.Function.Type.Attrs() cBinding := attrs.Contains("c") // create the function type funcType := v.functionTypeToLLVMType(n.Function.Type, false) functionName := mangledName if cBinding { functionName = n.Function.Name } // add that shit function = llvm.AddFunction(v.curFile.LlvmModule, functionName, funcType) if !cBinding && !n.IsPublic() { function.SetLinkage(nonPublicLinkage) } if ccAttr := attrs.Get("call_conv"); ccAttr != nil { // TODO: move value checking to parser? if callConv, ok := callConvTypes[ccAttr.Value]; ok { function.SetFunctionCallConv(callConv) } else { v.err("undefined calling convention `%s` for function `%s` wanted", ccAttr.Value, n.Function.Name) } } if inlineAttr := attrs.Get("inline"); inlineAttr != nil { function.AddFunctionAttr(inlineAttrType[inlineAttr.Value]) } /*// do some magical shit for later for i := 0; i < numOfParams; i++ { funcParam := function.Param(i) funcParam.SetName(n.Function.Parameters[i].Variable.MangledName(parser.MANGLE_ARK_UNSTABLE)) }*/ } }
func (v *AttributeCheck) CheckFunctionDecl(s *SemanticAnalyzer, n *parser.FunctionDecl) { v.CheckAttrsDistanceFromLine(s, n.Function.Type.Attrs(), n.Pos().Line, "function", n.Function.Name) for _, attr := range n.Function.Type.Attrs() { switch attr.Key { case "deprecated": case "unused": case "c": case "call_conv": case "inline": switch attr.Value { case "always": case "never": case "maybe": default: s.Err(attr, "Invalid value `%s` for [inline] attribute", attr.Value) } default: s.Err(attr, "Invalid function attribute key `%s`", attr.Key) } } }