Beispiel #1
0
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)
		}
	}
}
Beispiel #2
0
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))
		}*/
	}
}
Beispiel #3
0
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)
		}
	}
}